Qodana / Static Code Analysis Guide / What Is Taint Analysis?
When you’re building applications that handle untrusted inputs, especially anything exposed to the public internet, you’re constantly navigating the boundary between what’s trustworthy and what isn’t. Taint analysis exists to enforce that boundary.
It’s one of the most powerful techniques in static code analysis, and Qodana uses it to help developers spot vulnerabilities early, long before they ever appear in production.
This guide breaks down how taint analysis works, why it matters, and how it fits into modern development and CI pipelines.
Taint analysis traces the flow of untrusted data (“tainted”) through your application to determine whether it can reach sensitive or dangerous operations (“sinks”) without proper validation or sanitization.
In other words, it answers a simple question:
If yes, that’s a vulnerability.
This includes classic issues like SQL injection, path traversal, command injection, and insecure deserialization - but also modern framework-specific issues where data flows through layers of abstractions, async calls, serializers, or template engines.
Tainted data is anything your application cannot inherently trust. Typically, this includes:
The precise definitions vary per language and framework, and static analysis tools such as Qodana maintain language-specific models to capture these flows accurately.
Although taint analysis can get deeply technical, nearly every engine uses the same conceptual model.
A source is where tainted data enters the program. For example:
val username = request.getParameter("username")A sink is an operation that becomes dangerous if it receives untrusted input. Examples include:
URL or redirect constructors
Sanitizers are operations that validate, escape, filter, or structurally transform dangerous input. Proper sanitization stops the taint flow.
A good taint engine understands not just simple sanitization (e.g., escapeHtml()) but also contextual sanitization (e.g., SQL escaping differs from HTML escaping).
Real-world systems rarely operate in simple straight-line code. Modern applications include:
A taint engine must track the flow across all of these. That means understanding function arguments, return values, object fields, collections, streams, higher-level framework behaviors, and custom frameworks without explicit annotations.
Qodana’s language models include deep, framework-aware rules for JVM languages, letting it track taint through Spring, Ktor, Jakarta EE, Micronaut, and more

Static analysis engines transform your code into representations such as:
These graphs let the engine reason about how data moves across method calls and classes.
The engine tracks where tainted values go, through variable assignments, method returns, objects, collections, streams, and coroutines.
If tainted data reaches a sink without passing through a recognized sanitizer, Qodana flags a vulnerability.
This is where a mature engine matters, real-world code can generate noisy analysis. Qodana incorporates:
So, it catches real bugs without overwhelming developers.
val id = request.getParameter("id") // source
val query = "SELECT * FROM users WHERE id = $id" // taint flows
jdbcTemplate.execute(query) // sinkQodana would flag this because untrusted input reaches the SQL execution without sanitization.
A safe version might use prepared statements:
jdbcTemplate.query("SELECT * FROM users WHERE id = ?", id)Now the sink is protected by a framework-level sanitizer.

Qodana builds upon the JetBrains IDE engine, the same engine that powers IntelliJ IDEA’s intelligent inspections, and extends it for CI, team workflows, and large-scale repositories.
Qodana’s taint analysis includes:
It also integrates taint analysis results into broader security features:
✓ Vulnerability analysis
✓ Malicious dependency detection
✓ License compliance
✓ Security trend reports
✓ Organization-wide risk dashboards
This gives teams a single, unified security view of their code.
See Qodana’s taint analysis in action with this WebGoat demo by JetBrains security expert, Greg.

Even if you think your input is safe, taint analysis often exposes surprising flows that developers didn’t realize existed.
Good taint analysis complements good engineering habits. For example:
Teams using taint analysis consistently see fewer high-impact vulnerabilities and faster remediation times.
As applications scale and architectures get more distributed, taint analysis becomes essential. It provides a systematic way to prevent injection flaws and unsafe flows - especially in environments where developers rely on AI-assisted code generation.
Since Qodana’s inception, we’ve had Taint Analysis for PHP but now support has expanded. Qodana’s taint engine brings this capability directly into your IDE, CI/CD pipelines, and organization-wide dashboards, helping teams detect vulnerabilities early, at the point of development.
Watch the Taint Analysis livestream to learn more!
