SAST, DAST and dependency scanning: coverage and release decisions
Compare static analysis, dynamic testing and dependency scanning. Follow findings through verification, prioritization and release policy without treating a green scan as proof of safety.
TL;DR: Static analysis examines code, dynamic testing exercises a running application, and dependency scanning compares components with vulnerability knowledge. Combine them according to failure coverage, then verify findings and assign a concrete remediation or exception.
Different inputs expose different defects
Static application security testing, or SAST, analyzes source or other program representations. It can follow suspicious data flows, such as user input reaching a SQL query, without needing a deployed service. Its result depends on language support, modeling and analysis limits. The OWASP source-analysis overview explains the approach and its false-positive and false-negative limitations.
Dynamic application security testing, or DAST, sends requests to a running target and observes behavior. It can find a reachable injection or an exposed debug endpoint, but only within the routes, identities and states it exercises. Dependency scanning, often called software composition analysis, identifies included components and checks known vulnerability information. A version match establishes a lead about a component; it does not explain whether this application's deployed path is exploitable.
These findings converge on a decision with an owner. Three green dashboards can still leave a missing tenant authorization check untested.
Build a coverage matrix before adding tools
| Failure | Useful evidence | Gap to address separately |
|---|---|---|
| SQL constructed from untrusted input | Static data-flow finding and a safe reproduction | Paths unsupported by the analyzer |
| Vulnerable bundled library | Component/version match in the built artifact | Whether the affected behavior is present and reachable |
| Exposed administration route | Authenticated and anonymous dynamic tests | Routes the crawler never discovers |
| Cross-tenant data access | Explicit tests with two tenant identities | Business authorization rules absent from generic scanners |
OWASP Dependency-Check is one example of identifying dependencies and associating them with known vulnerabilities. Keep the inventory tied to the produced artifact, including transitive packages where the tool supports them. A clean repository lockfile is insufficient if the container adds a vulnerable operating-system package later in the build. Supply-chain graphs explain those additional inputs.
Work a finding through to a release decision
Suppose a fictional build contains an outdated image-processing library. The scanner reports a severe issue affecting a parser used by an upload endpoint. Confirm the exact installed version, the affected feature and the production route that reaches it. If untrusted uploads exercise that parser, an upgrade or isolation change has immediate value. Rebuild the artifact and verify the installed component after the fix; changing a manifest without regenerating the image leaves the deployed bytes unchanged.
Now suppose a similarly scored finding affects an optional desktop integration that the server build excludes. Preserve the evidence for that exclusion and make any exception specific to the artifact and vulnerability. Do not globally suppress the package name, because another service may include the affected component. Recheck when packaging or dependency resolution changes.
A release policy should name which verified conditions block promotion, which need an owner and deadline, and who may accept a temporary exception. Severity contributes to prioritization alongside exposure, exploitability and service impact. An exception needs an expiry or invalidation condition so yesterday's evidence does not silently approve a changed deployment.
A dynamic scan has an operational boundary
Run active scans only against explicitly authorized targets with an agreed test scope. ZAP's active-scan documentation explains that this operation attacks the target and can damage data or functionality. Use an isolated representative environment with synthetic data and controlled external integrations; a staging hostname that sends real invoices is still connected to a real effect.
Authentication matters. An anonymous scan of a login page gives almost no evidence about an authenticated upload API. Supply permitted test identities, verify that the scanner stays logged in, and measure which intended routes it reached. Pair the scan with explicit authorization tests because a generic crawler cannot infer that tenant A must never see tenant B's order.
In an interview, explain what a scan result can prove about a particular build. “Security ran successfully” is too broad. A useful statement identifies the artifact digest, tool/rule version, checked scope, unresolved findings and accepted exceptions. Tool completion itself is only evidence that a job ran.
Self-check: SAST reports no findings, dependency scanning is clean, and DAST reached only /login. Can you approve a new cross-tenant export feature from those results? You still need tests of the feature's authorization boundaries and actual authenticated routes. Add two-tenant positive and negative cases, confirm exported object access, and verify the tested artifact is the one proposed for release.
Apply these distinctions to Checkmarx release policy, where required scan engines, result filters and threshold decisions must all match the proposed candidate.