* ci: add asset build verification workflow
A CI pass that fails if generated files are out of date.
* chore: npm run assets
Signed-off-by: Xe Iaso <me@xeiaso.net>
---------
Signed-off-by: Xe Iaso <me@xeiaso.net>
* test(nginx-external-auth): bring up to code standards
Signed-off-by: Xe Iaso <me@xeiaso.net>
* fix(lib): close open redirect when in subrequest mode
Closes GHSA-cf57-c578-7jvv
Previously Anubis had an open redirect in subrequest auth mode due to an
insufficent fix in GHSA-jhjj-2g64-px7c. This patch adds additional
validation at several steps of the flow to prevent open redirects in
subrequest auth mode as well as implements automated testing to prevent
this from occuring in the future.
* docs: update CHANGELOG
Signed-off-by: Xe Iaso <me@xeiaso.net>
---------
Signed-off-by: Xe Iaso <me@xeiaso.net>
* fix!(policy/checker): make List and-like
This has the potential to break user configs.
Anubis lets you stack multiple checks at once with blocks like this:
```yaml
name: allow-prometheus
action: ALLOW
user_agent_regex: ^prometheus-probe$
remote_addresses:
- 192.168.2.0/24
```
Previously, this only returned ALLOW if _any one_ of the conditions
matched. This behaviour has changed to only return ALLOW if _all_ of the
conditions match.
I have marked this as a potentially breaking change because I'm
absolutely certain that someone is relying on this behaviour due to
spacebar heating. If this bites you, please let me know ASAP.
Signed-off-by: Xe Iaso <me@xeiaso.net>
Assisted-by: GPT-OSS 120b on local hardware
* fix(policy/checker): more explicit short-circuit
Signed-off-by: Xe Iaso <me@xeiaso.net>
---------
Signed-off-by: Xe Iaso <me@xeiaso.net>
Closes#1206
This can cause Anubis to have other issues, but at the very least these
issues are at the Anubis level, not the level of your target service so
it's less bad.
* Update nn.json
Signed-off-by: Sunniva Løvstad <github@turtle.garden>
* Update nn.json (2)
Signed-off-by: Sunniva Løvstad <github@turtle.garden>
* Change awkward wording
Proof of Work → work-proof, that is confirmation that someone is real through work (the computer works)
Signed-off-by: Sunniva Løvstad <github@turtle.garden>
---------
Signed-off-by: Sunniva Løvstad <github@turtle.garden>
* fix(lib): show error message detail when hitting some common flows
Instead of giving the user nothing to go off of, this patch gives them
an opaque blob of ROT-13 encoded base64. The logic is that if you are
smart enough to figure out how to decode this, you're probably smart
enough to either fix your broken client or give it to the adminstrator.
Signed-off-by: Xe Iaso <me@xeiaso.net>
* docs: update CHANGELOG
Signed-off-by: Xe Iaso <me@xeiaso.net>
* Update metadata
check-spelling run (pull_request) for Xe/show-error-state
Signed-off-by: check-spelling-bot <check-spelling-bot@users.noreply.github.com>
on-behalf-of: @check-spelling <check-spelling-bot@check-spelling.dev>
---------
Signed-off-by: Xe Iaso <me@xeiaso.net>
Signed-off-by: check-spelling-bot <check-spelling-bot@users.noreply.github.com>
* fix(lib): enable multiple consecutive slash support
Closes#754Closes#808Closes#815
Apparently more applications use multiple slashes in a row than I
thought. There is no easy way around this other than to do this hacky
fix to avoid net/http#ServeMux's URL cleaning.
* test(double_slash): add sourceware case
Signed-off-by: Xe Iaso <me@xeiaso.net>
* test(lib): fix tests for double slash fix
Signed-off-by: Xe Iaso <me@xeiaso.net>
---------
Signed-off-by: Xe Iaso <xe.iaso@techaro.lol>
Signed-off-by: Xe Iaso <me@xeiaso.net>
* feat(lib/challenge): expose ResponseWriter to challenge issuers
Signed-off-by: Xe Iaso <me@xeiaso.net>
* feat(metarefresh): randomly use the Refresh header
There are several ways to trigger an automatic refresh without
JavaScript. One of them is the "meta refresh" method[1], but the other
is with the Refresh header[2]. Both are semantically identical and
supported with browsers as old as Chrome version 1.
Given that they are basically the same thing, this patch makes Anubis
randomly select between them by using the challenge random data's first
character. This will fire about 50% of the time.
I expect this to have no impact. If this works out fine, then I will
implement some kind of fallback logic for the fast challenge such that
admins can opt into allowing clients with a no-js configuration to pass
the fast challenge. This needs to bake in the oven though.
[1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/meta/http-equiv
[2]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Refresh
Signed-off-by: Xe Iaso <me@xeiaso.net>
* docs: update CHANGELOG
Signed-off-by: Xe Iaso <me@xeiaso.net>
* feat(metarefresh): simplify random logic
Signed-off-by: Xe Iaso <me@xeiaso.net>
---------
Signed-off-by: Xe Iaso <me@xeiaso.net>
Signed-off-by: Xe Iaso <xe.iaso@techaro.lol>
Also, will allow to set cookie `SameSite` mode on command line or
environment. Note that `None` mode will be forced to ``Lax`` if
cookie is set to not be secure.
Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>
* Add option for difficulty JWT field
* Add DIFFICULTY_IN_JWT option to docs
* Add missing_required_forwarded_headers to lt translation via Google Translate
* docs(CHANGELOG): move CHANGELOG entry to the top
Signed-off-by: Xe Iaso <me@xeiaso.net>
---------
Signed-off-by: Xe Iaso <me@xeiaso.net>
Co-authored-by: Xe Iaso <me@xeiaso.net>
* fix(challenge): demote temporal assurance to 80% instead of 95%
Signed-off-by: Xe Iaso <me@xeiaso.net>
* fix(challenge/preact): wait a little longer to be extra safe
Signed-off-by: Xe Iaso <me@xeiaso.net>
* fix(challenge/metarefresh): wait a little longer to be extra safe
Signed-off-by: Xe Iaso <me@xeiaso.net>
* docs(CHANGELOG): add fix notes
Signed-off-by: Xe Iaso <me@xeiaso.net>
---------
Signed-off-by: Xe Iaso <me@xeiaso.net>
Some admins have noticed that clients are not waiting the right amount
of time in order to access a resource protected by the metarefresh
challenge. This patch adds a check to make sure that clients have waited
at least 95% (difficulty times 950 milliseconds instead of difficulity
times 1000 milliseconds) of the time they should.
If this scales, maybe time is the best way to go for Anubis in the near
future instead of anything else computational.
Signed-off-by: Xe Iaso <me@xeiaso.net>
* feat(localization): Add Vietnamese translation
* feat(localization): Add Vietnamese language translation
* feat(localization): Add record to CHANGELOG.md
* feat(localization): Add test case for Vietnamese
* fix(lib): ensure issued challenges don't get double-spent
Closes#1002
TL;DR: challenge IDs were not validated at time of token issuance. A
dedicated attacker could solve a challenge once and reuse it across
multiple sessons in order to mint additional tokens.
With the advent of store based challenge issuance in #749, this means
that these challenge IDs are only good for 30 minutes. Websites using
the most recent version of Anubis have limited exposure to this problem.
Websites using older versions of Anubis have a much more increased
exposure to this problem and are encouraged to keep this software
updated as often and as frequently as possible.
* docs: update CHANGELOG
Signed-off-by: Xe Iaso <me@xeiaso.net>
---------
Signed-off-by: Xe Iaso <me@xeiaso.net>
* Add option for customizable explanation text
* Add changes to CHANGELOG.md
* Replace custom explanation text in favor of static simplified text
Also includes translations for the simple_explanation using Google
Translate as a placeholder so tests pass.
---------
Signed-off-by: Xe Iaso <xe.iaso@techaro.lol>
Co-authored-by: Xe Iaso <xe.iaso@techaro.lol>
This was causing confusion and less technical users were thinking that
websites had been intruded upon, causing them to send me horrible things
over email.
All non-English strings were amended using Google Translate. Please fix
the localization as appropriate.
* Add JWTRestrictionHeader funktionality
* Add JWTRestrictionHeader to docs
* Move JWT_RESTRICTION_HEADER from advanced section to normal one
* Add rull request URL to Changelog
* Set default value of JWT_RESTRICTION_HEADER to X-Real-IP
* refactor: make challenge pages return the challenge component
This means that challenge pages will return only the little bit that
actually matters, not the entire component.
Signed-off-by: Xe Iaso <me@xeiaso.net>
* fix(web): move Anubis version info to be implicitly in the footer
Signed-off-by: Xe Iaso <me@xeiaso.net>
* fix(web): embed challenge ID into generated pages
Signed-off-by: Xe Iaso <me@xeiaso.net>
* fix(lib): make tests pass
Signed-off-by: Xe Iaso <me@xeiaso.net>
* test(lib/policy/config): amend tests
Signed-off-by: Xe Iaso <me@xeiaso.net>
* test(lib): fix tests again
Signed-off-by: Xe Iaso <me@xeiaso.net>
---------
Signed-off-by: Xe Iaso <me@xeiaso.net>
Signed-off-by: Xe Iaso <xe.iaso@techaro.lol>
* chore(web/js): delete proof-of-work-slow.mjs
This code has served its purpose and now needs to be retired to the
great beyond. There is no replacement for this, the fast implementation
will be used instead.
Signed-off-by: Xe Iaso <me@xeiaso.net>
* chore(web): handle building multiple JS entrypoints and web workers
Signed-off-by: Xe Iaso <me@xeiaso.net>
* feat(web): rewrite frontend worker handling
This completely rewrites how the proof of work challenge works based on
feedback from browser engine developers and starts the process of making
the proof of work function easier to change out.
- Import @aws-crypto/sha256-js to use in Firefox as its implementation
of WebCrypto doesn't jump directly from highly optimized browser
internals to JIT-ed JavaScript like Chrome's seems to.
- Move the worker code to `web/js/worker/*` with each worker named after
the hashing method and hash method implementation it uses.
- Update bench.mjs to import algorithms the new way.
- Delete video.mjs, it was part of a legacy experiment that I never had
time to finish.
- Update LibreJS comment to add info about the use of
@aws-crypto/sha256-js.
- Also update my email to my @techaro.lol address.
Signed-off-by: Xe Iaso <me@xeiaso.net>
* fix(web): don't hard dep webcrypto anymore
Signed-off-by: Xe Iaso <me@xeiaso.net>
* chore(lib/policy): start the deprecation process for slow
This mostly adds a warning, but the "slow" method is in the process of
being removed. Warn admins with slog.Warn.
Signed-off-by: Xe Iaso <me@xeiaso.net>
* docs: update CHANGELOG
Signed-off-by: Xe Iaso <me@xeiaso.net>
* feat(web/js): allow running Anubis in non-secure contexts
Signed-off-by: Xe Iaso <me@xeiaso.net>
* Update metadata
check-spelling run (pull_request) for Xe/purge-slow
Signed-off-by: check-spelling-bot <check-spelling-bot@users.noreply.github.com>
on-behalf-of: @check-spelling <check-spelling-bot@check-spelling.dev>
---------
Signed-off-by: Xe Iaso <me@xeiaso.net>
Signed-off-by: check-spelling-bot <check-spelling-bot@users.noreply.github.com>