Application Security Testing: SAST, DAST & SCA
Build application security testing into development. Covers static analysis (SAST), dynamic testing (DAST), software composition analysis (SCA), security testing in CI/CD, and triage workflows.
Application security testing catches vulnerabilities before attackers find them. SAST scans source code without running it. DAST probes running applications like an attacker would. SCA identifies known vulnerabilities in your dependencies. Together, they form a defense-in-depth testing strategy that catches different classes of vulnerabilities at different stages.
Testing Types Compared
| Type | What It Tests | When It Runs | Finds | Misses |
|---|---|---|---|---|
| SAST | Source code (static) | At commit/PR | Code-level flaws (SQLi, XSS patterns) | Runtime issues, config problems |
| DAST | Running application | Post-deploy (staging) | Runtime vulnerabilities, misconfigs | Code-level root cause |
| SCA | Dependencies | At build | Known CVEs in libraries | Zero-days, custom code flaws |
| IAST | Instrumented runtime | During testing | Both code and runtime issues | Performance overhead |
| Secrets Scanning | Source + history | At commit/PR | Leaked credentials, API keys | Encrypted secrets |
CI/CD Integration
security-pipeline:
stages:
- name: Pre-Commit
tools:
- gitleaks # Secrets in code
- pre-commit # Formatting, basic checks
- name: PR / Build (SAST + SCA)
tools:
- semgrep # SAST - pattern-based code scanning
- snyk-code # SAST - AI-powered
- npm-audit # SCA - dependency vulnerabilities
- trivy-fs # SCA - filesystem scanning
gate: "Block PR on HIGH/CRITICAL findings"
- name: Build (Container)
tools:
- trivy-image # Container image scanning
- syft # SBOM generation
gate: "Block build on CRITICAL CVEs"
- name: Staging (DAST)
tools:
- zap # OWASP ZAP dynamic scanning
- nuclei # Template-based vulnerability scanning
gate: "Alert on findings, manual review"
- name: Production
tools:
- waf-rules # Runtime protection
- runtime-monitoring # Anomaly detection
Semgrep SAST Rules
rules:
- id: sql-injection
patterns:
- pattern: |
cursor.execute(f"... {$USER_INPUT} ...")
- pattern: |
cursor.execute("... " + $USER_INPUT + " ...")
message: "Possible SQL injection. Use parameterized queries."
severity: ERROR
languages: [python]
- id: hardcoded-secret
pattern: |
$KEY = "sk_live_..."
message: "Hardcoded API key detected. Use environment variables."
severity: ERROR
languages: [python, javascript, typescript]
Triage Workflow
| Severity | Response Time | Action |
|---|---|---|
| Critical | < 24 hours | Block deploy, immediate fix, incident process |
| High | < 1 week | Fix in current sprint, track in backlog |
| Medium | < 1 month | Schedule in upcoming sprint |
| Low | Best effort | Add to tech debt backlog |
| False Positive | Immediate | Suppress with documented justification |
Anti-Patterns
| Anti-Pattern | Problem | Fix |
|---|---|---|
| Scan but never fix | Thousands of findings accumulate | Enforce gates (block on CRITICAL/HIGH) |
| SAST only | Misses runtime issues and dependency CVEs | SAST + DAST + SCA together |
| Scan in production only | Vulnerabilities already deployed | Shift left: scan in CI/CD |
| No false positive management | Alert fatigue, teams ignore findings | Tuned rules, suppression with justification |
| Security team owns all findings | Bottleneck, no developer ownership | Developers own findings in their code |
Checklist
- SAST tool configured (Semgrep, SonarQube, CodeQL)
- SCA tool configured (Snyk, Dependabot, Trivy)
- DAST tool configured (OWASP ZAP, Nuclei)
- Secrets scanning in pre-commit (Gitleaks, TruffleHog)
- CI/CD gates: block on CRITICAL/HIGH findings
- Triage process: defined SLAs per severity
- False positive management: suppress with documentation
- Developer training: secure coding practices
- Regular review: rule tuning, new vulnerability patterns
:::note[Source] This guide is derived from operational intelligence at Garnet Grid Consulting. For application security consulting, visit garnetgrid.com. :::