feat(go): wrapped-handler routes, XSS rule, and govwa SAST benchmark - #246
Merged
Merged
Conversation
Closes the gaps a benchmark against a real vulnerable Go app (govwa) surfaced. All changes are Go-only (route mapper + Go taint pack + benchmark), so no other language is affected. Route mapper — middleware-wrapped handlers: - `router.GET(p, Log(RequireAuth(h)))` is now recognized as a route (balanced- paren arg capture), where before only bare-name/inline handlers were — so idiomatic Go middleware chaining no longer yields zero routes. - Auth is credited only from a wrapping middleware CALL (name followed by `(`), never from a handler merely NAMED with an auth-ish word — marking a route authed off a handler name would be the dangerous direction (suppresses a real missing-auth). Innermost resolvable handler supplies handler_source. Go XSS rule (injection-go.yaml): - Flags user data cast to a template safe-string type (template.HTML/JS/ HTMLAttr/CSS/URL), which bypasses html/template auto-escaping (gosec G203). Implemented as pattern-regex, not an AST pattern, because the cast is a Go type conversion whose AST match needs type resolution that a cloned repo (no downloaded modules) lacks. A string-literal cast is excluded — no FP on static markup. go-sast benchmark target: - benchmarks/go_sast.py clones govwa at a pinned commit and scores CLASS-LEVEL recall (SQLi, XSS, vulnerable-dependency, missing-auth) — deliberately not pinned to line numbers or app symbols, so the engine stays app-agnostic. Opt-in (named or --all, never the default set); skips cleanly when git/network or go/gopls are unavailable. Wired into run_benchmarks.py. Verified: - govwa full scan: 7 -> 16 findings; routes 0 -> 20; missing-auth 0 -> 5; auth-verified 15/20; all four vuln classes caught. go-sast: 4/4 class recall. - SAST-injection fixture gate extended with a Go XSS case: 53/53, 0 FP. - Full suite: 2621 passed, 1 xfailed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ4QoTqRoYWE25CNoV2Wfy
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.
What
Closes the gaps a benchmark against the real govwa (Go Vulnerable Web App) surfaced. All changes are Go-only (route mapper + Go taint pack + benchmark) — no other language affected; full suite confirms no regressions.
1. Route mapper — middleware-wrapped handlers
router.GET(p, Log(RequireAuth(h)))is now a route (balanced-paren arg capture); before, only bare-name/inline handlers mapped, so idiomatic Go middleware chaining yielded zero routes. Auth is credited only from a wrapping middleware call, never a handler merely named with an auth word — marking a route authed off a handler name is the dangerous direction (suppresses a real missing-auth).→ govwa: 0 → 20 routes, 0 → 5 missing-auth, 15/20 auth-verified.
2. Go XSS rule
Flags user data cast to
template.HTML/JS/HTMLAttr/CSS/URL(bypasses auto-escaping; gosec G203).pattern-regex, not AST — the cast is a type conversion whose AST match needs type resolution a cloned repo lacks. String-literal casts excluded (no FP on static markup).→ govwa: 6 XSS, 0 FP on safe literals.
3.
go-sastbenchmark targetbenchmarks/go_sast.pyclones govwa at a pinned commit and scores class-level recall (no line/symbol overfit). Opt-in (named or--all), skips cleanly offline.→ 4/4: SQLi, XSS, vulnerable-dependency, missing-auth.
Verified
🤖 Generated with Claude Code
https://claude.ai/code/session_01EZ4QoTqRoYWE25CNoV2Wfy