P03 Lab 04 — SAST Taint-Analysis Engine
WARMUP: Chapter 6 (the scanner zoo). This is what SAST does under the hood.
The idea
Static Application Security Testing finds injection-class bugs by taint analysis: track whether
attacker-controlled data from a source (request.param) reaches a dangerous sink (db.query,
exec) without passing through a sanitizer (parameterize, escape). A tainted value reaching a
sink is a vulnerability; a sanitizer clears the taint. It's the universal "separate code and data"
rule (Phase 02 injection) made mechanically checkable — and it lets you see why SAST has false
positives (unreachable paths) and false negatives (taint through constructs it can't model).
What you build (lab.py)
analyze(program)— propagate taint through a statement list (Assign/Sink): sources taint, copies propagate, sanitizers clear, constants clean; emit aFinding(sink, tainted_var, source)for each tainted value reaching a sink.is_safe(program)— no tainted data reaches any sink.
Cases the tests cover
- Direct source→sink (vuln, with the originating source recorded); a sanitizer on the path clears it; taint propagates through chained copies; sanitizing a different variable leaves the raw flow vulnerable; constant reassignment clears taint; an untainted sink is safe; multiple findings reported in order.
Run
pip install -r requirements.txt
LAB_MODULE=solution pytest -q
pytest -q
Hardening / extensions
- Add branches/loops and a control-flow graph (this version is straight-line) and inter-procedural flow (taint across function calls).
- Model partial sanitizers (escapes for HTML but not SQL — context matters) and field-sensitivity.
- Emit SARIF and map each finding to a CWE (join with the Standards taxonomy lab).
Interview / resume
"Built a taint-analysis engine — sources → propagation → sanitizers → sinks — the core of SAST, demonstrating how static analysis finds injection and where its false positives/negatives come from."
Limitations: straight-line, intra-procedural, field-insensitive over a statement-list model (no CFG, no aliasing, no inter-procedural flow) — exactly the simplifications that drive real SAST's imprecision.