Static Analysis Coverage Gaps for Injection Vulnerabilities

SAST finds risky code patterns but cannot prove they're exploitable under attack.

· 8 min read
Cover illustration for “Static Analysis Coverage Gaps for Injection Vulnerabilities”
Injection Flaws · October 20, 2026 · 8 min read · 1,865 words

SAST finds dangerous code patterns, but it does not establish how an application behaves under attack. Engineering teams need continuous code scanning, dynamic testing, and expert-reviewed whitebox testing to tell which suspicious code poses an exploitable risk.

What SAST actually does when it scans for injection vulnerabilities

SAST parses source code or bytecode into structures that security rules can examine without running the application. These include an abstract syntax tree, or AST, and control flow graphs. Lexical analysis identifies tokens, while parsing builds the tree that represents the code. Semantic analysis looks at what code elements mean and how they relate to each other. Data flow analysis then follows how information moves through those structures.

For injection vulnerabilities, the central technique is taint analysis. The scanner follows untrusted input from a source, such as user input, toward a sensitive sink, such as a database query or shell call. It looks for paths where that input reaches the operation without a recognized sanitizer or parameterization step. Because no deployed environment is needed, SAST can in principle examine even rarely executed paths.

That gives engineering teams feedback they can use at commit or pull-request time, before code reaches production. The same scanning approach can surface hardcoded secrets, weak cryptographic algorithms, and unsafe calls such as Python's eval() and pickle.loads(). Integration into IDEs and CI/CD pipelines brings findings and remediation guidance into normal development work. Scan output also provides code-layer evidence that auditors for SOC 2, HIPAA, and ISO 27001 can reference. These are sound reasons to use SAST, provided that evidence is understood for what it proves.

Why the same design that makes SAST fast also makes it systematically incomplete

The scanner's independence from a running application is also its boundary. It reasons about a model of code. That design has three limits: the scanner does not know all the frameworks and sanitizers, lacks context on exposure, and cannot see runtime state directly. Better rules and tuning can improve the model. They cannot turn it into an observation of an attack.

Framework blindness creates false positives when the scanner does not recognize a protection. A parameterized query or Django auto-escaping may make a path safe even though its structure triggers an alert. Context blindness causes a different distortion by flattening differences in exposure. A SQL injection pattern callable only by an authenticated internal service with no user-controlled parameters is not the same risk as one on a public login form.

Runtime state adds another limit because authentication state, session context, deployment topology, and cloud configuration help determine exploitability. Their absence can leave both the severity and the existence of an attack path unresolved. Meanwhile, poorly tuned rules create alerts that nobody triages. Once developers stop trusting the findings, genuine risks can disappear into the noise.

Where the gaps fall: how SAST performs against each injection vulnerability class

Coverage is strongest where the dangerous pattern is visible and stable in the code itself. Hardcoded secrets, although not an injection class, provide a useful baseline. A credential or token can be found in code text without running the application. Even here, test fixtures, masked passwords, and placeholder values can trigger false positives. Purpose-built secret scanners can go further than generic SAST by checking whether the credentials they find are still active, so they verify more than the static match.

SQL injection and command injection are close to the textbook taint-analysis case. A scanner can follow user input into query construction or a shell call and flag unsafe handling. What it cannot establish from that pattern is whether the deployed path is reachable or whether a higher layer blocks the input. Database privileges also shape how much harm SQL injection can do. WAF rules, rate limiting, and input length constraints change the exposure assessment, even though their presence is not itself proof that the path is safe.

XSS also gives static analysis a recognizable flow from user input into HTML output without proper sanitization. Framework protections complicate that picture because React, Vue, and Django templates auto-escape output by default. A scanner that misses those protections can report risks the framework already blocks. For DOM-based XSS, when the payload is processed entirely by the browser's JavaScript engine and never reaches the server, server-side static analysis largely misses the relevant behavior.

For SSRF, the same request-making pattern has different consequences in a network-segmented deployment with no cloud metadata access and one with IAM roles attached and IMDSv1 enabled. SAST cannot observe the VPC configuration, role scope, or metadata endpoint reachability. Where roles have broad permissions, a successful exploit can give an attacker temporary credentials for storage, databases, and secrets managers.

Insecure deserialization exposes a similar divide between a visible entry point and an unproven attack. Java's native deserialization and Python's pickle.loads() are recognizable API calls. But exploitation may need a gadget chain that carries a malicious payload through several legitimate classes before it reaches a dangerous operation. Understanding that chain requires the available objects and runtime calls to be examined together. An API warning identifies a surface to investigate.

Pattern-based coverage is weakest for business logic and broken access control. A missing authorization check can leave syntactically valid code with no banned function and no suspicious taint flow. The defect is an absent restriction. Finding it requires understanding who should be allowed to do what. That intended authorization model is not supplied by code structure alone.

The false negative problem: exploitable paths that SAST never flags

Even when a finding is uncertain, it gives a team something to look into. A false negative gives the team no such place to start. Authentication bypass can depend on a particular sequence of authenticated and unauthenticated requests. Insecure direct object references, or IDOR, depend on whether the current identity is allowed to access the requested resource. A scan can miss those failures even when the code it examines is syntactically correct.

Race conditions depend on the relationship between concurrent requests, which a static snapshot does not demonstrate. Second-order injection separates storage of a malicious payload from its later execution, so taint analysis can lose the chain across requests. Deployment flaws add another blind spot, including debug mode, insecure CORS headers, and overly permissive cloud IAM policies. Reading application code cannot show how those controls are set in the deployed system.

A clean SAST report therefore establishes only that no targeted patterns were detected, leaving the state of the attack surface unverified. That difference matters most for growth-stage SaaS companies that ship often. Their exposed behavior can change between scheduled tests while the scan continues to pass. An absent finding is an unanswered question that the report does not display.

Why the compliance framing makes the gap worse

When scanning becomes a compliance checkbox, that unanswered question can vanish from the organization's view of risk. Teams produce evidence that a control ran and treat it as evidence that attacks would fail. The incentive then shifts toward scan coverage and finding counts. Closing a ticket because the code pattern changed can make the record look complete. Without retesting, it does not establish that the underlying weakness is closed.

The frameworks in the brief call for more than that narrow reading of scan output. SOC 2 auditors expect evidence for monitoring controls under CC4.1, and SAST results can contribute to it. But a finding list does not by itself demonstrate validation. ISO 27001:2022 Annex A 8.8 and 8.29 drive expectations for vulnerability management and secure development. Automated code review helps teams meet those aims, and retesting gives them evidence that remediation worked.

The research supplied for this article records the HHS HIPAA Security Rule update from January 2025 as a proposal that would require annual penetration testing if finalized. That distinction matters because a proposal must not be presented as an obligation already in force. A clean scan and a report showing that a specific attack was attempted and blocked answer different assurance questions.

What fills the gaps: how dynamic testing and whitebox pen testing cover what SAST cannot

Dynamic application security testing, or DAST, addresses the missing observation by testing a running application. Automated tools such as OWASP ZAP can test for runtime vulnerabilities including SQL injection, XSS, and SSRF. Authenticated testing and multi-step request sequences show how the application behaves in ways that code patterns on their own cannot. The server's responses help show whether the tested input leads to a dangerous outcome. That makes dynamic testing a complement to early code scanning.

SSRF shows why the environment must be part of that work. Testing the deployed behavior can establish whether the metadata endpoint is reachable, while access to cloud configuration provides the role and permission context. Together, those observations reveal what a successful exploit could yield in that environment. They also prevent two identical code patterns from being treated as identical risks.

Expert-reviewed whitebox pen testing brings access to the source and a person's judgment together with the runtime evidence. A skilled tester can look into gadget chains, check whether authorization follows the intended business rules, and test race conditions with requests timed precisely. These are not gaps that a generic automated scan can reliably close. Findings should be backed by working exploits so remediation addresses a demonstrated path. Retesting then checks whether that path has actually been blocked.

Continuous pull-request scanning connects those deeper tests to everyday development. A team shipping daily can change its attack surface faster than an annual engagement tracks. Automated scanning catches the code-level patterns it handles well, while whitebox tests at regular intervals check what those patterns mean in the current deployment and look for paths the scanner missed. Dynamic testing contributes the running application's behavior throughout that assessment. The coverage comes from the combination of continuous scanning, runtime testing, and expert review with cloud access.

How engineering teams should evaluate their current testing stack against these gaps

The first evaluation is whether the SAST program fits the codebase. Its rules should be tuned for the actual frameworks, ORMs, and sanitizers in use. The false positive rate and active triage show whether developers still treat alerts as useful signals. A closed finding should also have a clear meaning. Evidence that the deployed fix blocks the attack is stronger than evidence that the scanner no longer recognizes the code pattern.

The next evaluation concerns what the penetration test can see. Source code and cloud configuration access allow a different assessment from a black-box test against a deployed endpoint. For SSRF, the scope should cover both the request-making code and the cloud deployment where it runs. Reports should describe an environment-specific path to compromise and back findings with working exploits. A retest cycle should check that the path has been closed as well as record the code change.

Those criteria also make the conversation with auditors and enterprise customers more useful. A SAST report shows that code was scanned, while a penetration test report with exploit evidence and a retest letter documents discovery, remediation, and validation of specific paths. Rigorous testing and audit readiness therefore support each other when the evidence matches the claim. The goal is to build a testing stack around real exploitability so the security program finds risk.

Sources

  1. Vulnerabilities Mapping based on OWASP-SANS: a Survey for Static Application Security Testing (SAST)
  2. Many Tools, Few Exploitable Vulnerabilities: A Survey of 246 Static Code Analyzers for Security
Filed underInjection Flaws

More in Injection Flaws