This is based on private evaluation of a prerelease security product.
I cannot comment further other than I am impressed by its output.
This commit is a squash of several commits. The impactful commits
have details underneath markdown heading twos.
## fix(metrics): don't expose pprof by default
pprof[1] is the Go standard library profiling toolkit. It is invaluable
for diagnosing how Go programs perform in the wild. However it also is
able to expose secret data set with command line flags. This is not
ideal and should be mitigated by correctly configured firewall rules. We
don't live in a world where people correctly configure firewall rules,
so we have to fix things for people. Welcome to 2026.
[1]: https://pkg.go.dev/runtime/pprof
Ref: AWOO-001
## fix(honeypot/naive): cap r9k delay to one second
Otherwise this can get unbounded, which can cause problems with lesser
HTTP proxies such as Apache.
Ref: AWOO-002
## fix(policy): mend an edge case with subrequest auth and query strings
This fixes an unlikely edge case where using subrequest auth and query
strings with path based filtering can cause reality to differ from
administrator intent. This effectively strips the query string from
subrequest auth checks. This deficiency should be fixed in the future.
Ref: AWOO-004
## fix(expressions): mend possible nil pointer deref edge case
If Anubis just started up, load averages may not be set in memory. This
can cause a nil pointer dereference which could fail requests with weird
errors until the async thread sets the load averages.
Ref: AWOO-005
## fix(lib): mend case where domainless redirects could allow cross-domain redirects
Ref: AWOO-009
## fix(expressions): validate randInt bounds before rand.IntN
Non-positive or platform-overflowing arguments to the CEL randInt
helper used to reach rand.IntN unchecked, surfacing a CEL evaluator
error during request processing when policies passed
attacker-influenced values (e.g. contentLength). Reject non-positive
bounds and detect int narrowing explicitly, returning a typed CEL
error in both cases.
Ref: AWOO-010
Signed-off-by: Xe Iaso <[email protected]>
* feat(internal): add ListOr[T any] type
This is a utility type that lets you decode a JSON T or list of T as a
single value. This will be used with Redis Sentinel config so that you
can specify multiple sentinel addresses.
Ref TecharoHQ/botstopper#24
Assisted-by: GLM 4.6 via Claude Code
Signed-off-by: Xe Iaso <[email protected]>
* feat(store/valkey): add Redis(R) Sentinel support
Signed-off-by: Xe Iaso <[email protected]>
* chore: spelling
check-spelling run (pull_request) for Xe/redis-sentinel
Signed-off-by: check-spelling-bot <[email protected]>
on-behalf-of: @check-spelling <[email protected]>
* chore(store/valkey): remove pointless comments
Signed-off-by: Xe Iaso <[email protected]>
* docs: document the Redis™ Sentinel configuration options
Signed-off-by: Xe Iaso <[email protected]>
* fix(store/valkey): Redis™ Sentinel doesn't require a password
Signed-off-by: Xe Iaso <[email protected]>
* chore: spelling
Signed-off-by: Xe Iaso <[email protected]>
* chore: spelling
Signed-off-by: Xe Iaso <[email protected]>
---------
Signed-off-by: Xe Iaso <[email protected]>
Signed-off-by: check-spelling-bot <[email protected]>
* test: testcontainers improvements
Use the endpoint feature to get the connection URL for the container.
There are cases where localhost is not the correct one, for example when DOCKER_HOST is set to another machine.
Also, don't specify the external port for the mapping so a random unused port is used, in cases when there is already Valkey/Redis running as a container and port mapped externally on 6379.
* also remove this hack, doesn't seem necessary.
* (feat) Add cluster support to redis/vaultkey store
* (chore) Update CHANGELOG.md
* (fix) Disable maintenance notification on the Valkey store
* (fix) Valkey text fix and allow maintnotifications in spelling.
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.
* feat(decaymap): add Delete method
Signed-off-by: Xe Iaso <[email protected]>
* chore(lib/challenge): refactor Validate to take ValidateInput
Signed-off-by: Xe Iaso <[email protected]>
* feat(lib): implement store interface
Signed-off-by: Xe Iaso <[email protected]>
* feat(lib/store): all metapackage to import all store implementations
Signed-off-by: Xe Iaso <[email protected]>
* chore(policy): import all store backends
Signed-off-by: Xe Iaso <[email protected]>
* feat(lib): use new challenge creation flow
Previously Anubis constructed challenge strings from request metadata.
This was a good idea in spirit, but has turned out to be a very bad idea
in practice. This new flow reuses the Store facility to dynamically
create challenge values with completely random data.
This is a fairly big rewrite of how Anubis processes challenges. Right
now it defaults to using the in-memory storage backend, but on-disk
(boltdb) and valkey-based adaptors will come soon.
Signed-off-by: Xe Iaso <[email protected]>
* chore(decaymap): fix documentation typo
Signed-off-by: Xe Iaso <[email protected]>
* chore(lib): fix SA4004
Signed-off-by: Xe Iaso <[email protected]>
* test(lib/store): make generic storage interface test adaptor
Signed-off-by: Xe Iaso <[email protected]>
* chore: spelling
Signed-off-by: Xe Iaso <[email protected]>
* fix(decaymap): invert locking process for Delete
Signed-off-by: Xe Iaso <[email protected]>
* feat(lib/store): add bbolt store implementation
Signed-off-by: Xe Iaso <[email protected]>
* chore: spelling
Signed-off-by: Xe Iaso <[email protected]>
* chore: go mod tidy
Signed-off-by: Xe Iaso <[email protected]>
* chore(devcontainer): adapt to docker compose, add valkey service
Signed-off-by: Xe Iaso <[email protected]>
* fix(lib): make challenges live for 30 minutes by default
Signed-off-by: Xe Iaso <[email protected]>
* feat(lib/store): implement valkey backend
Signed-off-by: Xe Iaso <[email protected]>
* test(lib/store/valkey): disable tests if not using docker
Signed-off-by: Xe Iaso <[email protected]>
* test(lib/policy/config): ensure valkey stores can be loaded
Signed-off-by: Xe Iaso <[email protected]>
* Update metadata
check-spelling run (pull_request) for Xe/store-interface
Signed-off-by: check-spelling-bot <[email protected]>
on-behalf-of: @check-spelling <[email protected]>
* chore(devcontainer): remove port forwards because vs code handles that for you
Signed-off-by: Xe Iaso <[email protected]>
* docs(default-config): add a nudge to the storage backends section of the docs
Signed-off-by: Xe Iaso <[email protected]>
* chore(docs): listen on 0.0.0.0 for dev container support
Signed-off-by: Xe Iaso <[email protected]>
* docs(policy): document storage backends
Signed-off-by: Xe Iaso <[email protected]>
* docs: update CHANGELOG and internal links
Signed-off-by: Xe Iaso <[email protected]>
* docs(admin/policies): don't start a sentence with as
Signed-off-by: Xe Iaso <[email protected]>
* chore: fixes found in review
Signed-off-by: Xe Iaso <[email protected]>
---------
Signed-off-by: Xe Iaso <[email protected]>
Signed-off-by: check-spelling-bot <[email protected]>