Application Security Testing

SAST, DAST, and SCA Explained: What Each Tool Tests and When to Use It

SAST, DAST, and SCA each test a fundamentally different attack surface, which means no single tool covers everything and each one has blind spots the others can catch. Understanding what each approach actually tests — and where it stops working — is the prerequisite to building a layered program that generates signal rather than just volume.

What SAST Does (and What It Misses)

Static Application Security Testing (SAST) analyzes source code, bytecode, or compiled binaries without executing the program. The tool reads your code the way a reviewer would — looking at variable assignments, function calls, data flow paths, and known dangerous patterns — and flags locations where attacker-controlled input could reach a dangerous operation like a database query, shell command, or file write.

Because SAST runs against code rather than a running application, it integrates naturally into a developer's workflow. It can run on every pull request, on every commit, or as a pre-push hook. It has full visibility into every code path, including paths that are rarely exercised in normal testing. That makes it effective at finding issues like hardcoded secrets, dangerous deserialization patterns, or SQL injection sinks in code that no integration test has ever reached.

The fundamental limitation of SAST is that it cannot know what happens at runtime. It cannot see how configuration values are loaded, what permissions the running process actually has, whether a particular code path is reachable given the application's routing logic, or whether a framework's built-in protections neutralize the pattern the tool flagged. This is why SAST produces false positives: the code pattern looks dangerous in isolation, but runtime context makes it safe. In large codebases, false positive rates can become high enough that developers begin to ignore findings entirely, which defeats the purpose of running the tool.

SAST also cannot find vulnerabilities that only manifest at runtime. Business logic flaws, authentication bypass conditions that depend on session state, race conditions, and server-side request forgery vulnerabilities that depend on network topology are all outside the reach of pure static analysis. The SSRF found in Ghost’s webhook delivery system (CVE-2026-53945) is a clear example: Ghost used a safe HTTP library across the codebase, but the webhook path let an admin control the target URL—a runtime distinction no static scanner could draw from the code alone.

What DAST Does (and What It Misses)

Dynamic Application Security Testing (DAST) takes the opposite approach. Instead of reading code, it interacts with a running application the way an attacker would: sending crafted HTTP requests, observing responses, and inferring vulnerabilities from behavior. A DAST tool does not need access to source code. It can test any application it can reach over a network — including third-party components, compiled binaries, and legacy systems where source is unavailable.

Because DAST tests a real running environment, its findings have a higher baseline of exploitability. If a DAST tool successfully extracts data through a SQL injection payload, that injection point is confirmed to be reachable, functional, and unmitigated in the actual runtime environment. It finds the vulnerabilities that matter in production rather than the ones that exist only in theory.

DAST's limitations are the mirror image of SAST's strengths. It cannot cover code paths that its test cases never trigger. For an application with thousands of endpoints, complex authentication flows, or non-HTTP interfaces (GraphQL subscriptions, WebSocket handlers, internal RPC services), DAST coverage can be significantly incomplete. DAST also runs late — it requires a deployed or staging environment, which means it typically cannot run on every commit the way SAST can. Findings discovered in DAST often surface well after the vulnerable code was written, when the cost of fixing it is higher.

DAST finds runtime behavior problems but cannot tell you where in the codebase those problems originate. A DAST finding requires a developer to then manually locate and understand the vulnerable code path, which adds investigation time before remediation can begin.

What SCA Does (and What It Misses)

Software Composition Analysis (SCA) examines the open-source and third-party dependencies that make up the majority of modern application code. It inventories packages, maps them to known vulnerability databases (NVD, OSV, GitHub Advisory Database, and vendor-specific feeds), and flags any dependency version with a published CVE or advisory.

SCA addresses a genuinely different attack surface than either SAST or DAST. Most production application code is not code your team wrote — it is code pulled in from package managers, container base images, and transitive dependencies several layers deep. SCA tools provide visibility into that supply chain and give teams the information they need to evaluate and prioritize patching decisions.

The primary weakness of SCA is that it operates on version ranges and advisory metadata, not on actual usage. A dependency may have a critical CVE but your application may never call the vulnerable function, or the vulnerable function may be called but the input path may be controlled entirely by internal data that an attacker cannot reach. SCA cannot distinguish between a vulnerability that is reachable and actively exploitable in your application versus one that exists in a library you import but never exercise in a way that matters.

This gap between "the package has a CVE" and "this CVE is exploitable in our application" is the source of much SCA alert fatigue. Teams that take every SCA finding at face value spend significant engineering time upgrading dependencies to patch vulnerabilities that posed no practical risk to their specific deployment.

The Coverage Gap Between All Three

Mapping each tool's coverage reveals a pattern of overlapping blind spots that none of the three fills independently.

Tool Tests Runs when Primary gap
SAST Source code patterns, data flow, known-dangerous APIs Pre-commit, CI on every PR Cannot see runtime behavior; high false positive rate
DAST Running application behavior, HTTP responses, runtime state Against staging or pre-prod environment Limited coverage; misses code never exercised by test cases
SCA Dependency versions against advisory databases On manifest change or scheduled scan Cannot assess whether vulnerable code is actually reachable

The combined blind spot across all three is exploitability confirmation. SAST finds patterns that might be dangerous. DAST finds runtime behavior that is suspicious. SCA finds packages that have been tagged vulnerable. None of the three tools, on its own, can reliably answer the question that matters most to a security team: is this finding actually exploitable given how our application works in production?

That gap is where alert fatigue originates. When teams cannot distinguish confirmed-exploitable findings from theoretical ones, they either attempt to remediate everything (which overwhelms engineering capacity) or they begin ignoring findings (which leaves real vulnerabilities open).

How to Layer SAST, DAST, and SCA Effectively

Effective layering is less about running all three tools and more about using each at the right point in the development lifecycle and routing findings to the right owners.

Shift SAST left, but triage aggressively. SAST belongs in the developer workflow — running on every pull request or pre-push hook — because it can catch issues before code is merged. But raw SAST output without triage will overwhelm developers. Configure suppression rules for known false positive patterns in your stack, and establish a policy that only high-confidence findings block merges. Lower-confidence findings can go to a separate queue for security team review.

Use DAST to validate SAST findings, not to discover everything independently. Rather than running DAST as a separate broad scan, use it to confirm specific patterns that SAST flagged. If SAST identifies a potential SQL injection path in an endpoint, a targeted DAST probe against that endpoint in a staging environment can confirm whether the injection is actually reachable and exploitable. This approach treats DAST as a confirmation mechanism rather than a discovery mechanism, which is a more efficient use of the tool.

Apply SCA findings based on reachability, not just severity. Not all CVEs warrant immediate remediation. Prioritize SCA findings where the vulnerable function is in a code path your application actually exercises, where the attack vector is relevant to your deployment (network-accessible versus local-only), and where the CVSS score reflects actual exploitability rather than theoretical worst-case. Dependency updates that patch unreachable vulnerabilities should be batched into regular maintenance cycles rather than treated as urgent remediations.

Establish ownership for each tool's findings. SAST findings belong to the developer who wrote the code. DAST findings belong to the team responsible for the endpoint or service. SCA findings belong to whoever owns the dependency manifest. When findings lack clear owners, they stall in triage and go unfixed. Routing matters as much as detection.

Exploit Validation: The Missing Fourth Layer

Layering SAST, DAST, and SCA closes most of the detection gap, but it does not resolve the exploitability question. Each tool still produces findings that require human judgment to prioritize — and human judgment at the volume these tools generate is expensive and inconsistent.

Layering tools without validation just multiplies alert volume, not signal quality. Three tools generating unvalidated findings does not produce three times the signal; it produces three times the noise, distributed across three different dashboards.

The missing layer is automated exploit validation: a process that takes flagged findings and attempts to confirm whether they can actually be triggered in the context of the real application. Validation changes the fundamental nature of the output from a list of candidates to a list of confirmed issues. Our analysis of Hoppscotch (CVE-2026-50160) illustrates this directly: four individual weaknesses each appeared low-severity in isolation, but once the chain was validated end-to-end, a single unauthenticated HTTP request was sufficient for full server compromise.

Kira adds this validation step, confirming which flagged findings are actually reachable and exploitable in your codebase before surfacing them. Rather than presenting developers with a queue of patterns that might be dangerous, Kira delivers findings with proof — the specific conditions under which the vulnerability can be triggered. This is what separates a finding that demands immediate remediation from a finding that can wait for the next dependency update cycle.

For teams running all three traditional tools and still struggling with prioritization, validation is typically the missing step. It is not a replacement for a broader application security program, and it does not eliminate the need to run SAST, DAST, and SCA. It completes the picture by answering the question those tools cannot: which of these matters right now?

If you want to understand how validation fits into the broader comparison between static and dynamic approaches, the article on static scanners versus exploit validation covers the mechanics in more detail. And for a direct comparison of just SAST and DAST as detection methods, see the SAST vs. DAST breakdown.

FAQ

Do I need all three tools — SAST, DAST, and SCA — or can I start with just one?

You can start with one, and for most teams, SCA is the highest-return starting point because it addresses an attack surface (third-party dependencies) that is proportionally large in modern applications and produces findings that are relatively easy to act on. SAST comes next because it runs early in the development cycle and catches first-party code vulnerabilities before they reach production. DAST is the most operationally complex to set up (it requires a running environment and meaningful test coverage) and tends to produce the highest-confidence findings, so it works best as a later addition once the other two are producing clean signal. The goal is to reach a point where all three are running routinely, but there is no reason to wait until all three are ready before getting value from the program.

Why does my SCA tool flag vulnerabilities in dependencies I don't actually call?

SCA tools operate on package metadata and version numbers, not on runtime call graphs. When a dependency has a published CVE, the tool flags every project that includes that package version — regardless of whether the vulnerable function is ever called by application code. This is by design: the tool cannot safely assume that unreachable code is harmless, because reachability analysis requires running the application or performing deep static analysis that most SCA tools do not attempt. The practical consequence is that many SCA findings reflect theoretical exposure rather than confirmed risk. Teams that want to prioritize accurately need to overlay reachability information — either through manual review, through a static analysis tool that can trace call paths into dependencies, or through a validation layer that confirms whether the vulnerable code path can actually be triggered in the context of their application.

What is the best order to introduce SAST, DAST, and SCA into a CI/CD pipeline?

The recommended sequencing follows the development lifecycle from earliest to latest. Start by adding SCA to your manifest-level CI step so that dependency vulnerabilities are flagged whenever package files change — this requires minimal configuration and produces immediate signal. Next, integrate SAST into your pull request pipeline so that every code change is scanned before it merges. At this stage, invest time in tuning the tool's ruleset to your language and framework so that the false positive rate stays manageable. Finally, add DAST to your pre-production or staging deployment pipeline to catch runtime vulnerabilities that SAST missed. Each of these stages can be added incrementally; you do not need to configure all three at once. The common mistake is trying to add all three simultaneously and then spending weeks tuning each one while developers complain about blocked pipelines — a phased rollout avoids that friction.

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