Learning objectives
By the end of this module, you should be able to:
- Explain what SAST can and cannot prove.
- Triage a finding using source, sink, validation and reachability context.
- Design a CI gate that preserves actionable evidence.
Static analysis reasons about code
SAST examines source or intermediate representations without needing a running target. Rules can detect dangerous APIs, patterns and some data flows.
Finding ≠ exploit
A dangerous sink may be unreachable, protected by validation, or genuinely exploitable. Triage should preserve the code path and assumptions.
Rules are policy
A rule set changes what the organization considers detectable risk. Pin and review rule changes just like dependencies.
Worked example
Source-to-sink triage
input → validation → query builder → database
Question: can attacker-controlled data reach the sink without a safe parameterization boundary?
- Connect each finding to a concrete risk and control.
- Preserve evidence so a reviewer can reproduce the decision.
Core lab · account-free
Lab 03 — Triage a synthetic unsafe pattern
Goal: Separate detection from exploitability reasoning.
Before you start
- No cloud account required.
- Core lab uses bash/Python 3 and local files only.
STEP 1Create sample code
cat > /tmp/devsecops_app.py <<'PY'
def lookup(user):
return "SELECT * FROM users WHERE name='" + user + "'"
PY
STEP 2Detect concatenated SQL
python3 - <<'PY'
from pathlib import Path
s=Path('/tmp/devsecops_app.py').read_text()
assert 'SELECT * FROM users' in s and '+ user +' in s
print('review required: query concatenates input')
PY
STEP 3Write remediation
State why parameterized queries are a control and what test would prove the fix.
Verify
- The risky construction is identified.
- Remediation includes both code change and verification.
Expected outcome
- The lab produces a reviewable finding without claiming automatic exploitability.
Diagnose / troubleshoot
- If a rule flags generated/vendor code, scope scanning deliberately instead of globally suppressing it.
- If a finding is disputed, document the exact data-flow assumption.
Real-world connectionSAST is strongest when findings flow into normal code review with reproducible evidence.
Optional real-tool lab
Optional tool lab — Semgrep
Run Semgrep against a disposable local file.
Prerequisites
- Install the referenced open-source CLI only for the optional lab.
- Use an organization-approved pinned version in real CI; do not blindly use latest.
Cost / risk
- Expected cloud cost: none. Use only approved repositories and disposable training artifacts.
Warnings
- Never scan or publish real production secrets in a training lab.
- Scanner output is evidence for triage, not an automatic statement of exploitable risk.
TOOL 1semgrep --version
TOOL 2semgrep scan -l python -e '$X + $Y' /tmp/devsecops_app.py --error || true
Avoid these traps
Common mistakes
- Treating every rule as equally severe.
- Ignoring generated-code scope.
- Disabling a noisy rule without replacement or owner.
Knowledge check
Can you connect the finding to the control?
Three concept checks plus one scenario check.
1What does SAST primarily inspect?
Source code or related representations for risky patterns and data flows.
2What should triage preserve?
The rule, code location, source/sink path, validation assumptions and disposition.
3Why pin rule/config versions in CI?
Rule changes alter detection behavior and should be reviewable and reproducible.
4Scenario: a high-severity rule hits code that is unreachable in production. What next?
Document the reachability evidence and disposition; do not silently suppress the rule globally.