Watch
0
0
Fork
You've already forked hyperhive
0

swarm-authelia: match the metrics rules with or without a query string

Authelia 4.39.20 matches `resources` against the cleaned path plus
`?<query>` (authorization/types.go:94 NewObject, utils/url.go:11-34
URLPathFullClean), while nginx's `= /metrics` serves the request whatever
its query. `^/metrics$` therefore missed `/metrics?x=1`: both the collector
rule and the trailing `deny` were skipped and a plain session reached
`default_policy = one_factor`. The pattern is now `^<path>([?].*)?$` for
every published target.

Forgejo strips trailing slashes before routing (routers/common/
middleware.go stripSlashesMiddleware) and serves metrics without a token
when none is configured, so `forge.<swarm>/metrics/` reached its metrics
through the ungated `/` location. The forge vhost now answers
`= /metrics/` with 404; nginx merges slashes and decodes `%2F` before
matching, so that also covers `/metrics//` and `/metrics%2F`.

Part of #5205
This commit is contained in:
atlas 2026-10-13 10:52:51 +02:00 • committed by mara
commit 8eb11a91da
3 changed files with 96 additions and 10 deletions

View file

@ -84,7 +84,11 @@ let
parts = builtins.match "https://([^/]+)(/.*)" url;
target = {
domain = builtins.elemAt parts 0;
resources = [ "^${lib.escapeRegex (builtins.elemAt parts 1)}$" ];
# ⚠️ Authelia matches `resources` against the cleaned path PLUS the
# query string, while nginx's `= <path>` location ignores the query.
# A bare `^<path>$` therefore misses `<path>?x`, which the location
# still serves, and that request falls through to `default_policy`.
resources = [ "^${lib.escapeRegex (builtins.elemAt parts 1)}([?].*)?$" ];
};
in
if parts == null then