reqparamlimit

package
v0.78.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 1, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package reqparamlimit catches unclamped request-sourced integers flowing into limit/cap-shaped call parameters. A client-controlled limit is a denial-of-service lever: a request that says "limit: 9_999_999" makes the server size a search, query, or allocation to the attacker's number. Real instance: the MCP docs-search tool handler forwarded params["limit"] (type-switched out of the request map) verbatim into docs.SearchWithLimit, whose hit list then scaled with whatever the client sent (framework/mcp_introspection.go:282, the seed of this analyzer).

Lane: vettool (type-aware), NOT the contracts pattern lane. Two judgements need types.Info and defeat string-pattern rules:

  • the callee's parameter NAME at the argument position, resolved from the callee's types.Signature — docs.SearchWithLimit's second parameter is named "limit" whatever the import alias or selector spelling at the call site;
  • map type identity: only map[string]any-shaped indexes (string key, empty-interface element — the decoded-JSON params shape, named aliases included) count as request-sourced. Typed config maps (map[string]int) and struct fields never produce an extraction and stay silent.

Sanctioned postures that stay silent:

  • a clamp between extraction and use: any comparison of the extracted variable against a constant literal (limit <= 0, limit > 100) or a max*-prefixed identifier or field (limit > maxHits, limit > c.maxHits) in the straight line — this covers both reassignment clamps (limit = maxHits) and reject-guards (if limit > maxHits { return err }).
  • an expression clamp: limit := min(params["limit"].(int), 100) — a builtin min/max call anywhere in the assigning expression counts as clamped in place.
  • clean reassignment: limit = defaultLimit after extraction clears the taint, since the RHS carries none.
  • limits sourced from constants, config structs, or typed maps.
  • extraction feeding parameters whose name is outside the set (a string term, a bool flag) — only limit-shaped parameter names are sinks.

Heuristics, exactly as implemented:

  • extraction: a type assertion or type switch on m[K] where m is map[string]any-shaped and K is a string literal matching (?i)^(limit|max|hits|count|page_?size|batch_?size|top|take)$. The value may then flow through conversions and plain assignments; flow is local, forward, straight-line.
  • use: the tainted value appears in a positional argument whose callee parameter name matches the same set. Callee signatures resolve through types (function or method object, then the static type of the callee expression); signatures whose parameters are unnamed match nothing. When no signature is available at all, fall back to a call-site positional heuristic — only the FINAL positional argument is treated as limit-shaped — and builtins and conversions are excluded outright. The fallback is stated here for completeness: in compiling code the signature almost always resolves, so the fallback is effectively unreachable.
  • clamp: a comparison (==, !=, <, <=, >, >=) of a tainted variable against a constant literal or a max* identifier or field, appearing in an if/switch/for condition between extraction and use, clears that variable. Taint learned inside a conditional branch, loop body, or closure stays inside it (closures are checked as fresh functions with no inherited taint); assignments made inside type-switch clauses DO escape the switch, because the switch statement itself always executes.
  • one diagnostic per call site: the first matching argument is reported at the argument's position.

Index

Constants

View Source
const Doc = "report request-sourced limit-shaped map values passed to limit-shaped parameters without a clamp"

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name: "reqparamlimit",
	Doc:  Doc,
	Run:  run,
}

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL