SAST
An X-ray of the code without running anything: it finds vulnerable patterns before the first deploy.
What it is
(Static Application Security Testing) analyzes source code, bytecode or binaries without running the program. The scanner looks for dangerous constructs (SQL concatenation, , weak cryptography, ) and points to the file and line, in the format developers already consume.
The acronym hides three very different techniques: pattern matching (textual rules), data flow analysis (the famous ) and semantic analysis. Without understanding all three, the scanner output looks like magic, and false positives look like bugs.
From text to AST
Before any analysis, the code goes through a parser and becomes an AST (): each language construct becomes a typed node, and the scanner navigates this tree instead of reading loose text. That is what lets it ask things like 'is there a concatenation node inside a query call?'.
An innocent line of JavaScript becomes a tree like this:
const sql = "SELECT * FROM users WHERE id = " + req.query.id
VariableDeclaration
id: Identifier "sql"
init: BinaryExpression "+"
left: StringLiteral "SELECT * FROM users WHERE id = "
right: MemberExpression
req.query.idSource → sink: the heart of the analysis
The AST alone says a concatenation exists, not whether it is dangerous. The security question is a different one: does this data come from a trusted origin? Where does it end up?
Taint analysis answers by following the data: untrusted sources (user input, headers, query strings) are marked as 'tainted'. The engine propagates this mark through assignments, concatenations and function calls, and raises the alert when the mark reaches a sink: a point where the data becomes a command, query, HTML or file path.
In the example below, the flow is complete: it is born at req.query.id (source), crosses a concatenation (propagation) and ends inside db.query (sink):
app.get("/users", (req, res) => {
const id = req.query.id; // SOURCE
const sql = "SELECT * FROM users WHERE id = " + id; // propagation
db.query(sql, (err, rows) => res.json(rows)); // SINK
});What the scanner reports
The result is not 'a concatenation exists', it is the whole path, with the and a suggested fix. Something like:
server.js:3
SQL Injection (CWE-89) · high
taint: req.query.id -> id -> sql -> db.query()
fix: use a parameterized query (placeholder $1)The fix the engine accepts
Parameterizing the query breaks the taint: the user's value stops being code and becomes data. In taint analysis terms, the is a sanitizer (or barrier): the engine knows that specific path is clean and stops alerting on it.
app.get("/users", (req, res) => {
const sql = "SELECT * FROM users WHERE id = $1"; // fixed query
db.query(sql, [req.query.id], (err, rows) => res.json(rows));
});Where it fits in the pipeline
As early as possible: IDE plugins and pre-commit give feedback in seconds, and the full analysis runs on the PR and in the build stage. Broken critical rules fail the build () and block the merge.
Strengths
- 100% code coverage, including rarely executed paths
- finds the vulnerability early, when fixing it is cheap
- needs no running environment or credentials
Limitations
- false positives: when the engine cannot prove the path is safe (a custom sanitizer, for example), it alerts as a precaution, and triage is human work
- path explosion: analyzing every execution combination is expensive; engines use heuristics and can miss rare flows
- it is blind to runtime configuration, infrastructure and real behavior, which is DAST territory
connections on the map
- SASTstage: build/PRCI/CD
- Shift-leftanticipatesSAST
- SASTcomplementsDAST
- Threat modeling: think like the attacker before codingdefines what to testSAST
updated on 14/10/2026 · sources to go deeper · report an error
in other domains
- Reporting findings and driving remediationoffseca well-written finding becomes a rule and a test in the pipeline
- The verification loopvibecodingthe gate that applies to any author, human or agent
- A05 Injectionowaspit is the pattern that static analysis looks for in code
- Tool callingai-agentscatches injection in code; here the target is the tool argument
- Runbooks, response and post-incident hardeningsecopspost-incident hardening becomes a rule and a fix in code
Study before
Unlocks
test what you learned
Loading questions…