The Problem
A security team at a financial services company ran static analysis tools and found 847 vulnerabilities in their codebase. Their reachability scanner confirmed 312 of these could execute. The team spent six weeks addressing these issues, diverting engineers from feature work.
Three months later, a penetration test revealed an exploitable SQL injection vulnerability in the "reachable" code. The team had deprioritized it because the scanner marked it as "low severity" based on theoretical impact, not actual exploitability.
The vulnerability was exploitable because user input flowed directly from an API endpoint to a database query without proper sanitization. The reachability scan confirmed the code could run but didn't confirm an attacker could exploit it.
Timeline of Events
Week 1: Static analysis identifies 847 vulnerabilities
Week 2: Reachability analysis narrows the list to 312 "reachable" findings
Weeks 3-8: Engineers remediate based on severity scores, not exploitability
Week 12: Penetration test discovers exploitable SQL injection in deprioritized vulnerability
Week 13: Emergency remediation and incident response
Missing Controls
The team had scanning tools and a vulnerability management process, but three critical controls were missing:
1. Input Validation at Trust Boundaries
The endpoint accepted user input without validation or sanitization before use in the SQL query. PCI DSS v4.0.1 Requirement 6.2.4 mandates that applications validate all input from untrusted sources. The reachability scan confirmed the code path existed but didn't verify if an attacker could inject malicious input.
2. Exploitability Assessment
The team prioritized based on theoretical severity scores, not demonstrated exploitability. OWASP ASVS v4.0.3 Section 14.2 requires security testing to verify exploitability, not just the presence of vulnerable code patterns. Reachability confirms that code can run, not that an attacker can abuse it.
3. Attack Surface Mapping
The team didn't map which vulnerabilities were reachable from actual ingress points. ISO/IEC 27001:2022 Control 8.25 requires identifying and managing vulnerabilities considering actual threat exposure. The SQL injection was reachable from a public API endpoint, but the team's process didn't distinguish between code reachable from user input and code reachable only through internal function calls.
What Standards Require
PCI DSS v4.0.1 Requirement 6.2.4: Applications must validate all input from untrusted sources before it reaches sensitive operations like database queries.
OWASP ASVS v4.0.3 Section 1.14: Security testing must verify exploitability, not just the presence of vulnerable code. Your scanner can identify a SQL injection pattern but can't tell if an attacker can reach it with malicious input.
NIST 800-53 Rev 5 Control RA-5: Requires vulnerability monitoring and scanning, but also analyzing scan results in the context of your environment. A vulnerability that's reachable but not exploitable from any attacker-controlled input is a different risk than one directly exposed through a public API.
The gap: Most static analysis tools tell you what's reachable from your code entry points. They don't tell you what's reachable from an attacker's perspective.
Lessons and Action Items
1. Map Attacker-Controlled Inputs to Potential Impacts
Don't just scan for vulnerable code patterns. Trace the flow from every point where an attacker can inject input (API endpoints, file uploads, query parameters) to every sensitive operation (database queries, system commands, file operations). You can do this manually by:
- Listing every public endpoint in your application
- Identifying which parameters accept user input
- Tracing those parameters through your code to find where they're used in sensitive operations
- Marking any path that lacks validation as exploitable
2. Prioritize Based on Demonstrated Exploitability
Create a triage matrix that considers:
- Is the vulnerability reachable from user input?
- Does the input pass through validation?
- What's the actual impact if exploited?
A SQL injection in an admin function requiring authentication and input validation is lower priority than the same vulnerability in a public API endpoint with no validation, even if both are "reachable."
3. Update Your Vulnerability Management Workflow
Add an exploitability assessment step between scanning and remediation. For each finding:
- Can an attacker reach this code path with malicious input?
- What validation exists between the input and the vulnerable operation?
- What's the actual impact based on your environment, not theoretical severity?
This approach isn't about ignoring vulnerabilities. It's about fixing the ones that matter first.
4. Test Your Assumptions
Run penetration tests targeting vulnerabilities your team deprioritized based on reachability alone. You'll quickly learn which of your "low priority" findings are actually exploitable.
5. Implement Input Validation at Trust Boundaries
Every point where your application accepts external input is a trust boundary. Implement validation at these boundaries:
- API endpoints: Validate against schemas
- File uploads: Check file types and scan content
- Query parameters: Whitelist acceptable values
- Form inputs: Validate format and length
Don't rely on validation deeper in your code. By the time input reaches your business logic, it should already be validated and sanitized.
The financial services team now runs exploitability analysis before prioritizing remediation. They still find hundreds of vulnerabilities but fix the 20 that attackers can actually exploit first, not the 312 that are merely reachable.



