Add LangSec recognizer for /announce#2
Merged
Conversation
…validation Splits HandleAnnounce into a pure recognizer + executor following the LangSec principle (Sassaman & Patterson, "The Science of Insecurity"): recognize the input grammar completely before any business logic runs. - internal/tracker/recognize.go: RecognizeAnnounce(url.Values) returns a typed AnnounceParams with bounded info_hash/peer_id, port 1-65535, non-negative stats, PeerEvent enum, NumWant capped at 1000, and BEP 23 compact default. Pure function — no DB, no globals, no logging. - internal/tracker/announce.go: HandleAnnounce now does only prune → auth → recognize → execute. executeAnnounce reads exclusively from AnnounceParams; no q.Get or strconv past recognition. Auth extracted to authenticatePasskey. - internal/tracker/recognize_test.go: 30+ table-driven subtests covering every rejection and accept path. - internal/tracker/announce_test.go: pid20() helper migrates fixtures to BEP 3 20-byte peer IDs; new tests for short peer_id, bad port, bad event, and negative stats rejections. Rejections use the existing BEP 3 bencoded failure_reason wire format with typed reasons — strictness is in the reason, not the HTTP code.
This was referenced May 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Splits
HandleAnnounceinto a pure recognizer + executor, applying the LangSec principle from Sassaman & Patterson's The Science of Insecurity: recognize the input grammar completely before any business logic runs. Eliminates the shotgun-parser pattern of inlineq.Get+strconv+ silent fallbacks.internal/tracker/recognize.go—RecognizeAnnounce(url.Values) (AnnounceParams, error)returns a typed struct with boundedinfo_hash/peer_id, port 1–65535, non-negative stats,PeerEventenum,NumWantcapped at 1000, and BEP 23Compactdefault. Pure function — no DB, no globals, no logging.HandleAnnounce— now does only prune → auth → recognize → execute.executeAnnouncereads exclusively fromAnnounceParams; noq.Getorstrconvpast recognition. Passkey auth extracted toauthenticatePasskey(it's path-based, orthogonal to query grammar).internal/tracker/recognize_test.go— 30+ table-driven subtests covering every rejection and accept path.internal/tracker/announce_test.go—pid20()helper pads test fixtures to BEP 3 20-byte peer IDs; new tests for short peer_id, bad port, bad event, and negative stats rejections.Rejections use the existing BEP 3 bencoded
failure_reasonwire format with typed reasons (e.g.Invalid announce: peer_id must be exactly 20 bytes, got 8) — strictness is in the reason, not the HTTP code.This is Priority 1 of 3 from the LangSec analysis. P2 (bounded bencode validator for
.torrentparsing) and P3 (peer wire-protocol state machine) remain open as separate PRs.Test plan
go test ./...— all packages greengo vet ./...— cleanfailure reasonfield; valid announces return peers normallypeer_idenforcement is acceptable for real-world clients🤖 Generated with Claude Code