SAST, DAST & Dependency Scanning
SAST reads your source without running it, DAST probes the live application through HTTP, and dependency scanning checks the libraries in your build for known vulnerabilities. Learn when each runs, how they complement each other, and how to wire them into CI as a gating security test.
What is this?
SAST (Static Application Security Testing) analyzes source code without executing it, DAST (Dynamic Application Security Testing) probes a running application through its HTTP interface, and dependency scanning matches resolved library versions against vulnerability databases like the NVD. Together they form the automation core of application security, each covering a blind spot the other tools cannot see.
Why do you need it?
- SAST finds flaws at the commit stage — seconds after they are written — when they are cheapest to fix.
- DAST validates real behavior through the HTTP surface, catching runtime and configuration issues SAST misses.
- Dependency scanning flags known CVEs in libraries that neither SAST nor DAST can reliably detect.
- Automated gates in CI prevent vulnerable code from ever reaching an environment.
- The tools produce the evidence trail that audits and compliance reviews ask for.
Mental model
A proofreader, a health inspector and a supplier audit
SAST, DAST and dependency scanning
The proofreader checks the manuscript (code) for mistakes; the inspector visits the kitchen while it runs (the live app); the audit reviews where your ingredients come from (libraries). Each catches what the other two cannot see.
How it works
- SAST parses the source and applies rules — pattern matching and taint analysis — to flag risky patterns like SQL concatenation or unsafe deserialization.
- DAST crawls and fuzzes a running instance, sending attack payloads and observing responses for errors, anomalies and confirmed signals.
- Dependency scanning compares the resolved lockfile versions against vulnerability databases such as the NVD and OSV.
- Findings are triaged by severity and context, deduplicated, and routed to the owning team.
- CI gates fail the build on critical and high findings, while lower-risk findings flow into the backlog as tracked items.
Where each tool sits in a CI/CD pipeline.
Key commands
semgrep scan --config .semgrep/ --json -o sast-report.jsonRun your custom SAST rules and write machine-readable results.
npm audit --json | jq -r '.metadata.vulnerabilities.severity'Check known-vulnerability severities in the resolved dependency set.
{"info":0,"low":1,"moderate":0,"high":2,"critical":0}grype dir:. -o tableScan a directory (or with grype image: a container image) against a CVE database.
docker run -t ghcr.io/zaproxy/zaproxy zap-baseline.py -t http://localhost:8080 -r report.htmlRun an OWASP ZAP baseline DAST scan against a local target and export an HTML report.
curl -sI http://localhost:8080/Confirm the target is reachable before starting a DAST pass.
HTTP/1.1 200 OK
jq -r '.results[] | [.check_id, .extra.severity] | @tsv' sast-report.json | sort -uSummarize SAST findings by rule and severity for the triage step.
Examples
A Semgrep rule that blocks SQL concatenation at commit time
# .semgrep/sqli.yaml — catch SQL built by concatenation or joinrules: - id: node-sql-concat languages: [javascript] message: Possible SQL injection. Use parameterized queries. severity: ERROR metadata: cwe: ["CWE-89"] owasp: ["A03"] patterns: - pattern-either: - pattern: $DB.query($X + $Y) - pattern: $DB.query($X + $V) - pattern: $DB.query($X.concat($V)) # Run it in CI:# semgrep scan --config .semgrep/ --severity ERROR# curl -sI https://staging.example.com/ | grep -i content-security-policy# npm audit --json | jq -r '.metadata.vulnerabilities.severity'The rule uses pattern-either to match three shapes of string-built queries, tags the finding with CWE-89 and OWASP A03 so it can be triaged and aggregated, and runs at ERROR severity so the CI gate fails. The comments show the companion checks: a DAST header assertion and a dependency audit command, because a single tool alone would leave the other two attack surfaces uncovered.
In production
- A merge gate fails the build when SAST reports a critical or high finding on the changed lines.
- Dependency scanning runs on every build and weekly against the full lockfile, alerting on newly published CVEs.
- DAST baseline scans run against every staging deploy; authenticated full scans run on release candidates.
- Findings route to the owning team with CWE/OWASP mappings so they are prioritized and fixed like defects.
Best practices
- Start SAST in diff mode to reduce noise, then widen scope as rules are tuned.
- Tune and baseline false positives instead of silently ignoring findings.
- Scan the locked, resolved dependency set (lockfile), not just the manifest.
- Give DAST valid test credentials so authenticated surfaces are actually exercised.
- Treat the tools as a tripwire, not the whole program — pair them with code review and manual testing.
Common mistakes
- Treating a clean SAST run as proof that an application is secure.
- Running DAST without credentials, so the authenticated half of the app is never scanned.
- Auto-suppressing findings to keep the gate green.
- Scanning manifests instead of lockfiles, missing the real resolved versions.
Common issues
SAST flags an internal helper as unsafeA false positive from coarse taint analysis.
Add a source/sink annotation or a path-sensitivity rule, and document the decision in the rule's metadata.
DAST baseline reports nothing on an app that is clearly vulnerableThe scan ran unauthenticated or the payloads were blocked.
Run an authenticated scan and confirm the target's WAF permits the tool's user-agent and request rate.
npm audit reports a high-severity advisory with no fixNo patched version of the affected package exists yet.
Pin the affected component, apply a workaround such as a configuration flag, and track the advisory for the fix release.
Debugging tips
- Reduce a SAST hit to a minimal reproducer to tell a false positive from a real flaw.
- Cross-check a DAST alert against SAST and dependency results for the same code path.
- When a tool misses a real bug, write a custom rule or a regression test and commit it with the fix.
Interview checkpoint
Hands-on lab
- Write and run a custom Semgrep rule that flags SQL concatenation
- Run a dependency scan and interpret the severity summary
- Run an OWASP ZAP baseline scan against a local target
- Combine the three results into a single CI gate decision
Automated Security Gate: SAST + DAST + Dependencies
50 min · advanced
Quick quiz
Which tool analyzes source code without executing the application?
A clean SAST report guarantees the application has no vulnerabilities.
A dependency with a known critical CVE has no patched version. Which response is most appropriate?
Cheat sheet
semgrep scan --config .semgrep/SAST rules in CIzap-baseline.py -t <url>DAST baseline scannpm audit --jsonnpm dependency scangrype dir:.Image/dir CVE scanosv-scanner -r .OSV database scanjq -r '.results[].extra.severity'Triage SAST output