Security linters are great at catching local hygiene issues: hardcoded tokens on line 42, unescaped output in a template, or unparameterized queries within a single database wrapper. But real-world attackers do not attack isolated lines of code — they exploit data flow across architectural boundaries.
When untrusted input enters in an API controller, passes through three service layers, and triggers an execution sink in a database repository, single-file scanners are blind to the reachability path.
1. Cross-Service Second-Order SQL Injection
Single-file scanners search for string concatenation inside SQL statements. If a value is read from an internal cache or trusted database row before being formatted into a query, pattern matchers assume it is safe.
In modern microservices, tainted user input often enters via an asynchronous event or message queue and is executed downstream. Without cross-file taint path reachability analysis, this vulnerability remains undetected.
// events/consumer.go — looks clean, receives payload from queue
func HandleOrderCreated(msg amqp.Delivery) {
order := parsePayload(msg.Body)
// Vulnerable sink: order.CustomFilter originates from external user input
db.Raw(fmt.Sprintf("SELECT * FROM items WHERE status = '%s'", order.CustomFilter))
}2. Server-Side Request Forgery (SSRF) with Dynamic DNS Rebinding
SSRF guards that check IP addresses using simple regex fail when user-supplied hostnames resolve to private subnet IPs (such as 169.254.169.254 in cloud environments) after DNS resolution.
A true security analysis must verify whether the network client implements deterministic socket dialer guards that validate IP addresses at connect time, rather than relying on naive URL string checks.
- Pattern linters only check if the URL string starts with 'http://' or 'https://'.
- They cannot verify whether the HTTP client is configured with custom dialer controls.
- Deterministic AST analysis verifies that the round-tripper or dialer enforces private CIDR blocking.
3. Broken Object Level Authorization (BOLA / IDOR)
BOLA occurs when an endpoint accepts an entity identifier without validating that the authenticated session owns that entity. The query itself looks completely secure (using parameterized queries), but the authorization predicate is missing.
Because single-file scanners only look for syntax errors or SQL injection, they see valid parameterized SQL and produce zero alerts.
4. Prototype Pollution via Deep Merge Utilities
In TypeScript and JavaScript codebases, untrusted JSON payloads merged into configuration objects can overwrite Object.prototype. If the deep-merge helper is defined in a shared library file and called in an API route, neither file reveals the vulnerability when inspected in isolation.
// utils/merge.ts
export function deepMerge(target: any, source: any) {
for (const key of Object.keys(source)) {
if (typeof source[key] === "object") {
target[key] = deepMerge(target[key] || {}, source[key]); // Prototype pollution if key is '__proto__'
} else {
target[key] = source[key];
}
}
return target;
}5. Insecure Deserialization Across Interface Boundaries
When deserializing untrusted binary or JSON payloads into polymorphic interface types, malicious types can trigger arbitrary code execution during instantiation. Lint rules that match function names cannot resolve dynamic runtime implementations.
6. Path Traversal with Canonicalization Bypass
Calling path.join with user-supplied filenames without verifying that the resolved path stays within the base directory root is one of the most common file access vulnerabilities.
7. Server-Side Template Injection (SSTI)
Evaluating user-provided strings inside template engines (such as Jinja, Handlebars, or Liquid) turns simple formatting into remote code execution. Catching this requires following the string variable from HTTP request body all the way into the template compiler.