Files
mcp/internal/rules/cors_rules.go
T

49 lines
1.4 KiB
Go

package rules
import (
"go/ast"
"go/token"
"strings"
)
// The web/mw CORS convention: mw.CORS uses exact-origin matching and rejects "*"
// at construction (panic). Passing "*" is the trap this rule catches before runtime —
// allow-all is done with mw.CORSAllowAll(), gated by env in application code.
func init() {
registered = append(registered,
Rule{
ID: "cors.wildcard-noop",
Severity: SeverityError,
Module: "web",
Check: checkCORSWildcard,
},
)
}
// checkCORSWildcard flags any call to <pkg>.CORS(...) whose arguments contain a
// "*" string literal — which mw.CORS rejects (panics) at boot.
func checkCORSWildcard(c *Context) []Finding {
var hits []Finding
ast.Inspect(c.File, func(n ast.Node) bool {
call, ok := n.(*ast.CallExpr)
if !ok || !strings.HasSuffix(exprName(call.Fun), ".CORS") {
return true
}
for _, arg := range call.Args {
ast.Inspect(arg, func(m ast.Node) bool {
lit, ok := m.(*ast.BasicLit)
if ok && lit.Kind == token.STRING && strings.Trim(lit.Value, `"`) == "*" {
hits = append(hits, Finding{
Message: `mw.CORS with "*" panics at construction — "*" matches no real origin (exact-match only)`,
Hint: "Use mw.CORSAllowAll() for local development, or list explicit origins.",
Line: c.Fset.Position(call.Pos()).Line,
})
}
return true
})
}
return true
})
return hits
}