Static Security Analysis
Attacking the code before it runs. Taint tracking, dataflow analysis, and pattern-based scanners (Semgrep, CodeQL) ask: “is there any path through this program where an adversary’s input reaches a dangerous sink?” A sensor of exploitable structure, not of known-bad strings.
In practice
A scanner reading is a source-to-sink path with a severity attached, not a bare pattern match:
semgrep --config p/owasp-top-ten src/
src/api/search.py:31: Possible SQL injection (high)
query = "SELECT * FROM items WHERE name = '%s'" % request.args["q"]
taint: request.args["q"] -> cursor.execute(query)
The value is the path. The finding is not “this string looks dangerous” but “input from here reaches that sink through these lines,” and the reading takes minutes because the intermediate steps are printed.
Severity is the scanner’s estimate, not the exploitability. A high finding behind an authenticated, sanitized code path may matter less than a medium one on an anonymous endpoint, and the scanner knows neither the auth model nor the traffic. Which is why triage reads the path first and the badge second, and why the same finding can be a blocker in one service and a note in another.
Response playbook
When the scanner fires:
- Trace the full path before judging severity. The scanner shows the chain; confirm whether anything in between already sanitizes, authenticates, or bounds the input.
- If reachable, fix at the sink. Parameterized queries, escaping APIs, allowlists. Point fixes outlive pattern fixes.
- If unreachable, record why. A one-line justification at the finding site keeps the next reviewer from redoing the triage.
- Fix the class, then add the rule. If the sink exists in ten other places, the scanner’s job is to find all ten; wire that rule into CI as blocking before the next one ships.
- Treat untriaged findings as broken builds. A backlog of undated security findings is a queue that never drains.
How it gets gamed
- Severity downgrade by triage. Marking a finding “won’t fix” with a one-word justification is the cheapest override available to a reviewer. The meta-signal is the ratio of suppressed to confirmed findings, and the age of the suppressed ones.
- Baseline erosion. Freezing the finding count in a baseline file and only failing on new ones, while the baseline quietly grows forever because “old findings are someone else’s problem.”
- Rule-set narrowing. Disabling taint rules because they are noisy and keeping only the pattern matches, which detect the least of the three.
- Scanner shopping. Running the tool that finds the fewest issues in review and calling it “our SAST.”
What it cannot detect
Vulnerabilities in the composition of services, in configuration, or in the dependencies’ runtime behavior — those belong to fault injection and live chaos. And a clean scan says nothing about attacks that arrive through valid inputs: fuzzing covers that side.
Security is a deeper topic than this catalog covers. SAST is one sensor in the adversarial family — it asks whether an adversary’s input can reach a dangerous sink — but the broader practice of application security (threat modeling, penetration testing, dependency vulnerabilities, runtime exploit detection) deserves its own resources. See OWASP and the CWE for dedicated treatment.
Related sensors
References
Publications
- An Empirical Study on the Effectiveness of Security Code Review —
- Eliminating Memory Safety Vulnerabilities at the Source —