name: static-taint-analysis description: Use when implementing static taint/dataflow analysis, interprocedural taint tracking, vulnerability analyzer plugins, Bandit-like checks, B620/B621/B622/B623/B624 rules, or source-to-sink rules for SQL injection, shell injection, path traversal, SSRF, XSS, request.args/form/cookies, sys.argv, input(), os.environ, import aliases, nested functions, f-strings, percent formatting, .format(), or Python walrus/NamedExpr propagation.
Static Taint Analysis
Use this for source-to-sink vulnerability checks, especially when hidden tests count findings and include false-positive fixtures.
Core Workflow
- Write the spec as tables before coding:
- sources;
- propagation forms;
- sanitizers;
- sinks;
- exact severity, confidence, CWE, and test IDs.
- Keep source, sanitizer, and sink matching exact unless the spec says to infer broader families. Broad sink matching often passes positive tests but fails false-positive tests.
- Track taint at expression level and assignment level. Process
Assign,AnnAssign,AugAssign, andNamedExpr/walrus. - Treat walrus as both an expression and an assignment:
(x := tainted)returns tainted and storesxas tainted for later expressions. - Propagate taint through multi-hop assignments, concatenation, f-strings,
%formatting,.format(), containers used by formatting, and ordinary function calls unless the callee is an explicit sanitizer. - Resolve import aliases before sink matching. Include
import module as aliasandfrom module import name as alias. - For nested functions, preserve outer-scope taint for closure reads while letting parameters shadow outer names.
- Record a finding at every matching sink call whose checked argument is tainted. Hidden tests often assert a minimum count, not just pass/fail.
Python AST Checks
- Handle
ast.NamedExpranywhere_expr_tainted()can see an expression. - For tuples, lists, sets, and dicts, return tainted if any contained value is tainted.
- For
ast.BinOp, check both sides. For%formatting, include tuple and dict members on the right side. - For
ast.JoinedStr, check each formatted value. - For method calls such as
.format(), check the receiver and arguments. - For call passthrough, return tainted when any argument or keyword is tainted unless the callee is a spec sanitizer.
Validation Matrix
Create or run focused tests for:
- each source feeding each sink at least once;
- every sanitizer preventing only the sink family it is supposed to protect;
- non-sanitizer wrappers such as
str(),float(),html.escape(), oros.path.normpath()still preserving taint unless listed in the spec; - false-positive fixtures for non-spec sinks;
- alias imports for every sink family;
- nested functions and closures;
- walrus inside sink arguments, walrus assigned before sinks, and walrus inside nested propagation;
# nosecor equivalent suppression at the sink line;- expected issue counts, not only whether at least one issue appears.
Safety Rules
- Do not mark parameterized SQL unsafe when taint is only in the params and the query string is untainted.
- Do not add broad sinks like arbitrary
session.get()orio.open()when the spec names only specific modules/functions. - Keep confidence/severity/CWE stable across all variants of the same rule.
- Run baseline tests plus the new targeted tests; taint plugins easily break existing analyzer behavior through over-broad matching.