Application Security Testing

SAST vs. DAST: Understanding the Trade-offs for Shift-Left Security

SAST and DAST test fundamentally different things: one reads your code without running it, the other interacts with your running application. Understanding what each method can and cannot see is the prerequisite for building a testing program that catches real vulnerabilities without burying developers in noise.

Static Application Security Testing (SAST) and Dynamic Application Security Testing (DAST) are the two foundational methods in application security testing, and they are often discussed as competing approaches when they are better understood as complementary ones. SAST analyzes source code or bytecode directly without executing it. DAST sends requests to a running application and interprets responses. Each method has blind spots the other does not have, which is why relying on only one of them always leaves meaningful attack surface untested.

How SAST Works

A SAST tool parses your source code (or compiled bytecode) and builds an internal representation of the program—typically a combination of an abstract syntax tree, a control flow graph, and a data flow graph. It then applies rules that describe known vulnerability patterns against these representations. The two main analytical techniques are:

  • Pattern matching — flagging code constructs that match signatures of known-bad patterns. Fast and low in false negatives for well-known vulnerability types, but prone to false positives because the pattern may exist without being exploitable in context.
  • Taint analysis — tracking the flow of untrusted input (sources) through the program to potentially dangerous operations (sinks), with sanitization functions checked in between. More accurate than pattern matching, but computationally heavier and sensitive to the completeness of the data flow model.

The advantage of SAST is that it requires no deployed environment. You point it at a repository and it produces results. It can run on every pull request as part of a pre-merge gate, which is what "shift-left" originally described: moving security testing earlier in the development lifecycle so issues are caught before they reach production.

SAST also has visibility into the full codebase—including code paths that are difficult to reach through automated HTTP-level testing. Authentication bypass logic buried in a rarely-executed branch, insecure deserialization in a background worker, or a missing authorization check in an admin-only API can all be surfaced by SAST without requiring an authenticated session against a running application.

How DAST Works

A DAST tool operates entirely from the outside. It has no access to source code—it only observes the application's HTTP interface. The core loop is: crawl the application's endpoints, generate crafted inputs for each parameter and path, send those inputs, and analyze responses for indicators of vulnerability.

What DAST is testing is the application as it actually behaves at runtime, with its real configuration, its real middleware stack, its real authentication system, and its real infrastructure. When a reflected XSS payload returns in a response without sanitization, that is observed directly—not inferred from code. When an authentication flow fails to properly invalidate a session token, DAST can detect that through behavioral observation. SSRF vulnerabilities like the one found in Ghost’s webhook handling (CVE-2026-53945) are a concrete example: the vulnerable path was only distinguishable from the safe ones at runtime, when an admin-supplied URL was actually sent to an HTTP client.

This runtime visibility is the core strength of DAST. It observes what actually happens, not what the code suggests should happen. An ORM that sanitizes queries at runtime eliminates a SQL injection risk that SAST would flag, without the SAST tool knowing about the sanitization. DAST would not flag it either, because the actual HTTP request with a SQL injection payload would be handled safely.

The practical constraints of DAST are well-known: it requires a deployed, configured, seeded test environment with working authentication. Setting up that environment correctly—so the DAST scanner can access authenticated endpoints, interact with all application flows, and not corrupt production data—is non-trivial. For this reason, DAST typically runs on a schedule against staging environments rather than on every commit.

What Each Method Misses

The coverage gap between SAST and DAST is significant enough that running only one of them leaves substantial attack surface unexamined.

Dimension SAST DAST
What it analyzes Source code or bytecode; no running application needed Running application via HTTP; no source code access needed
Runs in CI/CD on PRs Yes; fast enough for pre-merge gates No; requires deployed environment
False positive rate Higher without tuning; many flagged patterns are not exploitable in context Lower; findings are based on observed runtime behavior
Authentication coverage Can analyze auth logic in code; cannot test actual session handling Can test authenticated flows if configured correctly
Dependency vulnerabilities Limited; needs separate SCA layer Indirect; only if the vuln manifests in HTTP behavior
Business logic flaws Difficult; requires semantic understanding of business rules Better; can observe unexpected state transitions and access control failures
Infrastructure misconfigs None; outside code scope Partial; visible headers, CORS, and TLS settings are detectable
Runtime environment impact Cannot account for middleware sanitization at runtime Fully accounts for runtime behavior; no false positives from safe middleware

SAST misses anything that is only determinable at runtime: whether middleware actually sanitizes input, whether authentication logic functions correctly as a system, whether CORS headers are configured securely, and whether indirect object references are properly access-controlled. DAST misses anything that requires code-level visibility: vulnerabilities in code paths that are not easily reachable via HTTP, insecure cryptographic choices that do not produce observable behavioral differences, and logic errors that only manifest under specific data conditions.

The False Positive Problem

In practice, the most significant operational difference between SAST and DAST is not coverage—it is false positive rate. SAST tools, particularly without significant tuning and suppression effort, commonly produce findings that are not exploitable in the application's actual deployment context. A taint analysis path that looks dangerous in isolation may be fully mitigated by a sanitizer function that the tool's data flow model does not recognize. A pattern match may fire on test code that is never deployed to production.

DAST has a lower false positive rate because a finding represents something that was actually observed in the running application. If a reflected XSS payload returns unsanitized in a response, the application is vulnerable—there is no code path ambiguity. However, DAST is not immune to false positives: timing-based injection tests can produce false positives under load, and crawling logic may misinterpret application state.

Running both tools without a validation layer just doubles the alert volume. If SAST produces findings it cannot confirm are exploitable, and DAST produces findings it cannot correlate to root cause in code, the combined output is a larger backlog that is still not prioritized by actual exploitability. Adding more scanners to an unvalidated pipeline amplifies the noise problem rather than solving it.

Where Each Tool Fits in CI/CD

The shift-left principle holds that security testing should happen as early as possible in the development lifecycle, because the cost of fixing a vulnerability increases with each stage it passes through. Both SAST and DAST can contribute to this, but at different points in the pipeline.

SAST in the development phase

SAST is the natural fit for developer-facing feedback. It runs against code without a deployed environment, produces results in minutes, and can be integrated into pre-commit hooks, PR checks, and IDE plugins. The friction of running SAST is low enough that it can realistically be part of every code change. The challenge is suppressing enough noise that developers trust the results—a scanner that flags numerous irrelevant issues on every PR trains developers to ignore all scanner output.

DAST in staging and pre-release

DAST belongs in a stable environment that closely mirrors production. It is typically scheduled nightly against a staging environment or triggered on release candidate builds. Authenticated DAST scans that can exercise protected application functionality produce substantially more valuable results than unauthenticated crawls, which only see the application's public surface. API DAST—testing against an OpenAPI or GraphQL schema rather than crawling—provides more systematic coverage of API endpoints than crawler-based approaches.

Combining SAST and DAST Without Doubling Noise

The right way to combine SAST and DAST is not to simply run both and hand developers a merged list of findings. The goal is a pipeline where each tool contributes distinct signal, and where the combined output is more actionable than either alone.

The key addition is a validation layer between scanner output and developer backlog. Rather than asking developers to determine which SAST findings are actually exploitable and which DAST results have code-level root causes they can address, a validation step does that work first. This is where tools like Kira change the operational picture: rather than passing raw SAST and DAST output to engineering teams, Kira's validation layer confirms which findings from either method are actually exploitable in the application's context, reducing the triage burden and ensuring that remediation effort goes toward real vulnerabilities. As an example, four chained weaknesses in a NestJS API (CVE-2026-50160) that static scanners individually assessed as low severity combined into a CVSS 10.0 full compromise—a result only exploit validation could surface.

Correlation between SAST and DAST findings is also valuable: when a SAST finding and a DAST finding point to the same underlying vulnerability, that convergence increases confidence in both results. ASPM platforms (see What Is ASPM? Application Security Posture Management Explained) can perform this correlation across tools, though the quality of the correlation depends on the quality of the individual findings going in. For concrete examples of how combined analysis surfaces real vulnerabilities in production code, see Kira’s research.

For a broader view of how SAST and DAST fit alongside SCA in a complete testing program, see Application Security Testing: A Complete Guide for Engineering Teams. And for a comparison of traditional scanning approaches against exploit-validation-first methods, see Static Scanners vs. Exploit Validation: What the Difference Actually Means for Your Team.

FAQ

Can SAST replace DAST in a CI pipeline?

No, and trying to do so leaves a category of vulnerabilities systematically untested. SAST operates on code and cannot observe runtime behavior—which means authentication logic, session handling, CORS configuration, runtime sanitization behavior, and access control enforcement are all effectively invisible to it. These are exactly the areas where DAST provides signal. A team running only SAST may have strong coverage of code-level injection patterns while being completely blind to whether their authentication system can be bypassed in practice. The right frame is not which tool replaces the other, but which tool is appropriate at which stage: SAST in the development phase on every PR, DAST in staging on a schedule or on release candidates. Both are necessary for comprehensive coverage.

Why does my SAST tool report so many false positives compared to DAST?

SAST works from an incomplete model of the program. It traces data flows through code but cannot account for everything that happens at runtime: whether a framework-level sanitizer is intercepting input before it reaches a sink, whether a method call resolves at runtime to a safe implementation, whether a code path is reachable in the actual deployment configuration, or whether a finding is in test code that never runs in production. DAST has lower false positive rates because it observes actual application behavior—if a payload returns unsanitized, the vulnerability is real; if it does not, the finding does not get raised. The trade-off is that DAST cannot see into the code and cannot explain why a vulnerability exists, only that it does. Reducing SAST false positives requires tuning: suppressing rules that fire on patterns your framework handles safely, marking test code as out of scope, and building suppression lists for known-safe patterns in your specific codebase.

What types of vulnerabilities can only DAST find?

Several vulnerability classes are reliably detectable only through dynamic testing against a running application. Authentication and session management flaws—session fixation, predictable session tokens, improper logout handling, concurrent session issues—require an actual authentication system to test against. CORS misconfiguration is observable from response headers but is not determinable from code alone. Server-side request forgery (SSRF) in many forms requires crafted inputs to a running service to confirm exploitability. Business logic vulnerabilities that depend on application state and the interaction between multiple requests are generally outside SAST's reach. Second-order injection vulnerabilities, where malicious input is stored and later executed in a different context, are often missed by SAST data flow analysis but catchable by DAST through multi-step interaction. Runtime environment issues like insecure TLS configuration, missing security headers, and information disclosure in error responses are also DAST territory.

Related resources

See what Kira finds in your stack.

Kira runs autonomously on your codebase and delivers verified, exploitable findings with proof. Not alerts. Not maybes.

Get started free