Application Security Testing

Application Security Testing: A Complete Guide for Engineering Teams

Application security testing is not a single tool or a single phase—it is a layered discipline that spans static analysis, runtime testing, dependency auditing, and exploit validation. This guide explains how those layers fit together and where each one earns its place in a real engineering workflow.

Application security testing (AST) is the systematic process of identifying, validating, and prioritizing security vulnerabilities in software before attackers can exploit them. An effective program combines multiple complementary testing methods—each with different visibility into the application—rather than relying on any single tool to catch every class of weakness.

What Application Security Testing Actually Covers

Many teams treat application security testing as synonymous with running a static analysis scanner on their repository. In practice, that covers only a fraction of the attack surface. A mature program addresses at minimum four distinct problem spaces:

  • Source code vulnerabilities — logic errors, injection flaws, insecure cryptography, and missing authorization checks that live in the code itself.
  • Runtime behavior — how the application actually responds to malformed input, unexpected state transitions, and authentication edge cases when running.
  • Third-party dependencies — known vulnerabilities in open-source libraries and transitive dependencies that your code pulls in.
  • Configuration and infrastructure — misconfigured cloud services, hardcoded secrets, overly permissive IAM policies, and insecure default settings that create exploitable conditions even when the application code is clean.

Each of these areas requires a different testing approach, and gaps in any one of them leave meaningful attack surface unexamined. The 2021 Log4Shell crisis is a useful reminder: teams with excellent static analysis practices were still exposed because the vulnerability lived in a dependency, not in their own code.

The Four Testing Layers Explained

Understanding what each method can and cannot see is the foundation for building a sensible testing program. The table below summarizes the key trade-offs.

Layer What it tests When to run Key limitation
SAST Source code and compiled artifacts; data flow, control flow, and pattern matching against known vulnerability patterns On every pull request; fast enough for pre-merge gates Cannot observe runtime behavior; high false positive rate without tuning
DAST Running application endpoints; HTTP responses, authentication flows, session handling Against staging environments; nightly or on release candidates Cannot see inside the code; limited to what is reachable via HTTP surface
SCA Third-party dependencies and their known CVEs; license compliance On every dependency update and on a schedule for newly disclosed CVEs Flags vulnerability presence, not exploitability in your specific context
Exploit Validation Whether flagged findings are actually reachable, triggerable, and exploitable given the application's specific logic and configuration As a triage filter after SAST/DAST/SCA produce findings Requires more compute and time than raw scanning; not yet universal across all finding types

These layers are not redundant—they are complementary. SAST finds patterns in code that DAST would never see because it does not execute the code. DAST finds authentication and session issues that SAST cannot reason about without runtime state. SCA finds dependency risk that neither SAST nor DAST covers at all. Exploit validation answers the question that all three leave open: does this actually matter?

Where Static Analysis Falls Short

Static analysis tools work by parsing source code and applying pattern-matching rules or data flow analysis to flag code constructs that resemble known vulnerability patterns. They are fast, they scale well, and they can run on every commit without a deployed environment. Those are real advantages.

The limitation is that static analysis operates on an abstraction of the program, not the program itself. A SAST tool sees that user input flows into a SQL query construction function. It cannot see that the ORM layer between those two points already parameterizes all queries. It flags the finding anyway. Over time, teams in high-velocity environments accumulate large volumes of findings, the overwhelming majority of which do not represent real exploitable conditions in the context of their specific application.

False positives are a productivity tax, not a safety net. When engineers learn that most scanner findings are noise, they stop reading the reports carefully. The real vulnerabilities that do get flagged get buried under the volume of irrelevant ones. A scanner that cries wolf too often becomes less effective at its core job than a scanner that reports fewer findings with higher confidence.

This is not an argument against static analysis—it is an argument for pairing it with a validation step. Static analysis should be the first pass that generates candidates, not the final word on what needs to be fixed.

Dynamic Testing and Why Runtime Matters

Dynamic application security testing (DAST) operates against a running instance of the application. It sends crafted HTTP requests, observes responses, and infers vulnerabilities from runtime behavior—reflected input in responses, unexpected error messages, timing differences, authentication bypass symptoms, and similar signals.

DAST catches a category of issues that static analysis fundamentally cannot: those that emerge from the interaction between the application and its environment. Insecure direct object references, CORS misconfigurations, session fixation flaws, and authentication logic errors often only become visible when you actually try to exercise them against a running system. A practical illustration: the SSRF vulnerability in Ghost’s webhook delivery (CVE-2026-53945) required runtime observation to confirm—the code used a safe HTTP library everywhere except the one path where an admin controls the target URL, a distinction invisible to static analysis alone.

The practical constraint with DAST is environment dependency. You need a deployed, seeded, and authenticated test environment to run it meaningfully. That is more infrastructure overhead than running a static scanner against a repository. For this reason, DAST typically runs against staging environments rather than on every PR, which means it is not part of the fastest feedback loop available to developers.

For a detailed comparison of the two approaches, see SAST vs. DAST: Understanding the Trade-offs for Shift-Left Security.

How Exploit Validation Changes the Math

The core problem with both SAST and DAST is that they generate findings—they do not confirm exploitability. A SAST tool flags potential SQL injection. A DAST tool observes a reflected parameter in an error message. Both results require human analysis to determine whether the finding is a real vulnerability in the application's specific deployment context, or an artifact of the tool's limited visibility.

Exploit validation addresses this gap directly. Rather than simply flagging a pattern or observing a symptom, a validation step attempts to confirm whether a finding is actually reachable and triggerable given the application's logic, its runtime configuration, and the data flows that actually exist. This changes the output from a list of potential issues to a list of confirmed ones—as we documented in CVE-2026-50160, where a CVSS 10.0 full compromise in Hoppscotch was confirmed only by chaining four individually low-severity weaknesses in a NestJS API.

This is where tools like Kira change the workflow. Rather than handing engineers a raw list of static analysis or dynamic testing results to manually triage, Kira runs an autonomous validation step that confirms whether each finding is actually exploitable in context. The practical result is that engineering teams spend their remediation time on issues that are real, not on chasing scanner noise.

For a broader look at how SCA fits alongside SAST and DAST, see SAST, DAST, and SCA: How the Three Testing Methods Fit Together.

Building a Testing Program That Scales

The goal of an application security testing program is not to run every possible tool—it is to get high-confidence signal on exploitable risk at a pace that engineering teams can actually act on. Here is a practical framework for layering the methods described above.

Start with what fits in CI/CD

Static analysis and SCA both integrate naturally into pull request checks. They run fast, require no deployed environment, and can block merges on critical findings. Set aggressive severity thresholds early—if you configure every medium finding to block a PR, you will drown the team in noise and the gates will get bypassed. Reserve hard blocks for high-confidence, high-severity results.

Add runtime testing against stable environments

DAST and interactive application security testing (IAST) require a running application. Build a stable staging environment that closely mirrors production and run dynamic tests against it on a schedule or on release candidates. Authenticated scans that can actually exercise protected functionality produce far more useful results than unauthenticated crawls.

Apply validation as a triage filter

Do not present raw scanner output to engineers as a backlog to work through. Use a validation step to separate confirmed exploitable findings from theoretical ones. This may be an automated tool, a manual triage process, or a hybrid. The output that reaches the engineering team should be a prioritized list of issues they can act on immediately, with enough context to understand the attack path.

Track coverage, not just findings

Counting findings is a lagging indicator. What you actually want to know is: what percentage of your application's attack surface is covered by each testing layer? Are new endpoints getting scanned? Are new dependencies getting audited? Is coverage degrading as the codebase grows? Those are the questions that tell you whether your program is scaling or quietly falling behind.

For a deeper look at the vulnerability management side of this—how to triage, prioritize, and track findings over time—see Vulnerability Scanning: What It Covers and What It Misses.

FAQ

How do I know which application security testing tool is right for my stack?

Start with the type of coverage you are missing, not the tool category. If you have no visibility into source code vulnerabilities, a SAST tool is the right starting point. If you have SAST but no runtime testing, DAST is the logical next layer. If your dependency exposure is unknown, SCA should be the priority. Most teams underinvest in exploit validation regardless of which scanning tools they run—a scanner that cannot tell you whether a finding is exploitable in your specific application context forces engineers to perform that triage manually, which does not scale. Language and framework support matter too: verify that any tool you evaluate has mature support for your primary languages before committing to it, since rule coverage varies significantly across ecosystems.

What is the difference between application security testing and penetration testing?

Application security testing (AST) refers to the systematic, often automated, process of scanning and testing an application for known vulnerability classes on a continuous or recurring basis. It is designed to integrate into engineering workflows and catch issues as code is written and deployed. Penetration testing is a targeted, time-boxed engagement where skilled practitioners attempt to compromise the application using the full range of techniques available to an attacker—including chaining multiple lower-severity findings, exploiting business logic flaws, and pivoting through infrastructure. The two are complementary: AST gives you continuous, broad coverage across common vulnerability patterns; penetration testing gives you adversarial creativity and depth that automated tools cannot replicate. Neither substitutes for the other in a mature security program.

How often should we run application security tests in a CI/CD pipeline?

The answer depends on the tool type. Static analysis and SCA are fast enough to run on every pull request and should be. They provide immediate feedback to developers before code merges, which is the most cost-effective point in the lifecycle to catch and fix issues. DAST is heavier and typically runs against a deployed staging environment, so it is usually scheduled nightly or triggered on release candidate builds rather than on every PR. Exploit validation runs as a triage step after scanners produce findings—it does not need to run on every commit, but should be applied to every finding before it goes into an engineering backlog. The key principle is that feedback should be as fast as possible without drowning developers in noise that causes alert fatigue.

Related resources

From the research: Kira has documented how these gaps manifest in real codebases—including an SSRF vulnerability that lived in Ghost’s webhook delivery system (CVE-2026-53945), where a safe HTTP library was used everywhere except the one admin-controlled path, and a CVSS 10.0 full compromise in Hoppscotch (CVE-2026-50160), where one unauthenticated request granted full server access by chaining four weaknesses that each appeared low-severity individually. See Kira’s full case study library for documented examples across production codebases.

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