Weighs the soul of incoming HTTP requests to stop AI crawlers

v1.15.1: Zenos yae Galvus: Echo 1 (#181)

* version 1.15.0 (#144)

Signed-off-by: Xe Iaso <me@xeiaso.net>

* cmd/anubis actually check the result with the correct difficulty

Signed-off-by: Xe Iaso <me@xeiaso.net>

* v1.15.1: Zenos yae Galvus: Echo 1

Signed-off-by: Xe Iaso <me@xeiaso.net>

---------

Signed-off-by: Xe Iaso <me@xeiaso.net>
Co-authored-by: Henri Vasserman <henv@hot.ee>

authored by

Xe Iaso
Henri Vasserman
and committed by
GitHub
f844fffd 4b8efcba

+22 -11
+1 -1
VERSION
··· 1 - 1.15.0 1 + 1.15.1
+12
docs/docs/CHANGELOG.md
··· 11 11 12 12 ## [Unreleased] 13 13 14 + ## v1.15.1 15 + 16 + Zenos yae Galvus: Echo 1 17 + 18 + Fixes a recurrence of [CVE-2025-24369](https://github.com/Xe/x/security/advisories/GHSA-56w8-8ppj-2p4f) 19 + due to an incorrect logic change in a refactor. This allows an attacker to mint a valid 20 + access token by passing any SHA-256 hash instead of one that matches the proof-of-work 21 + test. 22 + 23 + This case has been added as a regression test. It was not when CVE-2025-24369 was released 24 + due to the project not having the maturity required to enable this kind of regression testing. 25 + 14 26 ## v1.15.0 15 27 16 28 Zenos yae Galvus
+9 -10
lib/anubis.go
··· 145 145 } 146 146 147 147 type Server struct { 148 - mux *http.ServeMux 149 - next http.Handler 150 - priv ed25519.PrivateKey 151 - pub ed25519.PublicKey 152 - policy *policy.ParsedConfig 153 - opts Options 154 - DNSBLCache *decaymap.Impl[string, dnsbl.DroneBLResponse] 155 - ChallengeDifficulty int 148 + mux *http.ServeMux 149 + next http.Handler 150 + priv ed25519.PrivateKey 151 + pub ed25519.PublicKey 152 + policy *policy.ParsedConfig 153 + opts Options 154 + DNSBLCache *decaymap.Impl[string, dnsbl.DroneBLResponse] 156 155 } 157 156 158 157 func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { ··· 428 427 } 429 428 430 429 // compare the leading zeroes 431 - if !strings.HasPrefix(response, strings.Repeat("0", s.ChallengeDifficulty)) { 430 + if !strings.HasPrefix(response, strings.Repeat("0", rule.Challenge.Difficulty)) { 432 431 s.ClearCookie(w) 433 - lg.Debug("difficulty check failed", "response", response, "difficulty", s.ChallengeDifficulty) 432 + lg.Debug("difficulty check failed", "response", response, "difficulty", rule.Challenge.Difficulty) 434 433 templ.Handler(web.Base("Oh noes!", web.ErrorPage("invalid response")), templ.WithStatus(http.StatusForbidden)).ServeHTTP(w, r) 435 434 failedValidations.Inc() 436 435 return