From c669b47b570d222a9a902705adeff8fb26c989c4 Mon Sep 17 00:00:00 2001 From: Xe Iaso Date: Fri, 25 Apr 2025 15:02:55 -0400 Subject: fix(lib): make Anubis less paranoid (#365) Previously Anubis would aggressively make sure that the client cookie matched exactly what it should. This has turned out to be too paranoid in practice and has caused problems with Happy Eyeballs et. al. This is a potential fix to #303 and #289. --- docs/docs/CHANGELOG.md | 1 + docs/docs/admin/policies.mdx | 2 +- lib/anubis.go | 43 +------------------------------------------ lib/random.go | 9 --------- 4 files changed, 3 insertions(+), 52 deletions(-) delete mode 100644 lib/random.go diff --git a/docs/docs/CHANGELOG.md b/docs/docs/CHANGELOG.md index 2b38413..bedd38e 100644 --- a/docs/docs/CHANGELOG.md +++ b/docs/docs/CHANGELOG.md @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Set or append to `X-Forwarded-For` header unless the remote connects over a loopback address [#328](https://github.com/TecharoHQ/anubis/issues/328) - Fixed mojeekbot user agent regex - Added support for running anubis behind a base path (e.g. `/myapp`) +- Reduce Anubis' paranoia with user cookies ([#365](https://github.com/TecharoHQ/anubis/pull/365)) ## v1.16.0 diff --git a/docs/docs/admin/policies.mdx b/docs/docs/admin/policies.mdx index 975faef..8722d9e 100644 --- a/docs/docs/admin/policies.mdx +++ b/docs/docs/admin/policies.mdx @@ -241,6 +241,6 @@ In case your service needs it for risk calculation reasons, Anubis exposes infor | :---------------- | :--------------------------------------------------- | :--------------- | | `X-Anubis-Rule` | The name of the rule that was matched | `bot/lightpanda` | | `X-Anubis-Action` | The action that Anubis took in response to that rule | `CHALLENGE` | -| `X-Anubis-Status` | The status and how strict Anubis was in its checks | `PASS-FULL` | +| `X-Anubis-Status` | The status and how strict Anubis was in its checks | `PASS` | Policy rules are matched using [Go's standard library regular expressions package](https://pkg.go.dev/regexp). You can mess around with the syntax at [regex101.com](https://regex101.com), make sure to select the Golang option. diff --git a/lib/anubis.go b/lib/anubis.go index 70eb37e..026783e 100644 --- a/lib/anubis.go +++ b/lib/anubis.go @@ -353,48 +353,7 @@ func (s *Server) maybeReverseProxy(w http.ResponseWriter, r *http.Request, httpS return } - if randomJitter() { - r.Header.Add("X-Anubis-Status", "PASS-BRIEF") - lg.Debug("cookie is not enrolled into secondary screening") - s.ServeHTTPNext(w, r) - return - } - - claims, ok := token.Claims.(jwt.MapClaims) - if !ok { - lg.Debug("invalid token claims type", "path", r.URL.Path) - s.ClearCookie(w) - s.RenderIndex(w, r, rule, httpStatusOnly) - return - } - challenge := s.challengeFor(r, rule.Challenge.Difficulty) - - if claims["challenge"] != challenge { - lg.Debug("invalid challenge", "path", r.URL.Path) - s.ClearCookie(w) - s.RenderIndex(w, r, rule, httpStatusOnly) - return - } - - var nonce int - - if v, ok := claims["nonce"].(float64); ok { - nonce = int(v) - } - - calcString := fmt.Sprintf("%s%d", challenge, nonce) - calculated := internal.SHA256sum(calcString) - - if subtle.ConstantTimeCompare([]byte(claims["response"].(string)), []byte(calculated)) != 1 { - lg.Debug("invalid response", "path", r.URL.Path) - failedValidations.Inc() - s.ClearCookie(w) - s.RenderIndex(w, r, rule, httpStatusOnly) - return - } - - slog.Debug("all checks passed") - r.Header.Add("X-Anubis-Status", "PASS-FULL") + r.Header.Add("X-Anubis-Status", "PASS") s.ServeHTTPNext(w, r) } diff --git a/lib/random.go b/lib/random.go deleted file mode 100644 index 79cded4..0000000 --- a/lib/random.go +++ /dev/null @@ -1,9 +0,0 @@ -package lib - -import ( - "math/rand" -) - -func randomJitter() bool { - return rand.Intn(100) > 10 -} -- cgit v1.2.3