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 a Finding(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.