SAST
Static Application Security Testing (SAST): scan source for vulns BEFORE shipping. Tools, integration patterns, and how to avoid false-positive fatigue.
OWASP — SAST
EXAMPLE
# ===== What SAST is =====
# Tools that read SOURCE code (no execution) to find security bugs.
# Run in IDE, pre-commit hook, PR check, scheduled scan.
# Compared to DAST (runs against running app) and SCA (checks dependencies).
# ===== What SAST finds =====
# - Injection sinks (SQL, command, XSS)
# - Insecure crypto (MD5, ECB, hardcoded keys)
# - Hardcoded secrets / passwords
# - Insecure deserialisation
# - Path traversal patterns
# - Misconfigurations (TLS off, weak ciphers)
# - Known vulnerable patterns (specific to language / framework)
# ===== Tool landscape =====
# Semgrep open-source, fast, easy custom rules, multi-language
# CodeQL GitHub's; deep semantic analysis; SARIF output
# SonarQube enterprise UI; quality + security
# Snyk Code paid; great DX in PRs
# Checkmarx, Fortify, Veracode — enterprise SAST
# Per-language: bandit (Python), brakeman (Rails), gosec (Go), spotbugs (Java)
# ===== Semgrep in CI (recommended starting point) =====
# .github/workflows/semgrep.yml
name: semgrep
on: [pull_request]
jobs:
semgrep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: returntocorp/semgrep-action@v1
with:
publishToken: ${{ secrets.SEMGREP_TOKEN }}
config: >-
p/owasp-top-ten
p/security-audit
p/javascript
p/python
# Or run locally:
pip install semgrep
semgrep --config p/owasp-top-ten
# ===== CodeQL =====
# Free for public repos; configured via GitHub Actions:
- uses: github/codeql-action/init@v3
with: { languages: 'javascript,python' }
- uses: github/codeql-action/analyze@v3
# Results appear in Security tab as code scanning alerts.
# ===== Custom rules (Semgrep) =====
# rules/no-md5.yml
rules:
- id: no-md5
message: MD5 is broken; use SHA-256 or a password hash
languages: [python]
severity: WARNING
pattern: hashlib.md5(...)
semgrep --config rules/no-md5.yml
# ===== Triage workflow =====
# 1. Critical / High -> fix before merging
# 2. Medium -> ticket + deadline (e.g. 30 days)
# 3. Low / Info -> backlog
# 4. False positives -> suppress with a comment + reason
# Example: # nosem
# Or rule-level: paths.exclude or rule.exclude
# ===== Suppression discipline =====
# Suppressions WITHOUT a reason rot.
# Require:
# - Suppression comment with the rule id + WHY
# - Optional expiry date in the comment
# - Periodic audit of suppressions
# Example:
# nosem: javascript.lang.eval — reviewed by sec on 2024-04, eval input is a constant
# ===== Integrate where the team will read =====
# - IDE (Semgrep, CodeQL extensions) — earliest feedback
# - Pre-commit hooks — local fast checks
# - PR comments — most leverage; reviewers see findings inline
# - Nightly scans — catch large incidents
# ===== Choosing a ruleset =====
# Start with OWASP Top 10 + language-specific defaults.
# Add custom rules when you see patterns repeat in real bugs.
# Subtract rules that produce > 30% false positives within a quarter.
# ===== When SAST wins =====
# - Catches known patterns early
# - Cheap to add to existing CI
# - Custom rules encode team-specific don'ts
# - Required by many compliance frameworks
# ===== When SAST hurts =====
# - False-positive fatigue -> people stop reading findings
# - Blocking merges on low-severity findings
# - Long scan times slowing PRs
# - 'Coverage theatre' — rules count without quality
# ===== Patterns to internalise =====
# - SAST in PRs; surface inline, not in a dashboard nobody opens
# - Critical/High blocking; Medium ticketed; Low backlogged
# - Suppressions require reason + reviewer
# - Quarterly false-positive review
# ===== Pitfalls =====
# - Treating findings as bugs without triage
# - Suppression bombs (large 'nosem' rolls with no reason)
# - Scanning generated / vendored code
# - Running every ruleset at max severity -> teams ignore everything
Why it matters
SAST is hygiene built into the PR loop. Pick a tool (Semgrep is the friendly default), apply OWASP Top 10 + language packs, surface findings inline, gate Critical/High, ticket the rest. Discipline on suppressions and a quarterly false-positive review keeps the signal usable.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// Static analysis in CI: Semgrep, CodeQL, SonarQube. // Tune rules to your stack; fail PRs on new high findings.Try it Yourself »
Discussion
Loading…