Taint Analysis: WebGoat Demo
This blog post is a text version of the demo provided during the Taint Analysis Livestream: Exploring Hidden Dangers In Your Team’s Code. Today, we’ll use WebGoat as our test application to demonstrate Qodana’s taint analysis functionality. This application is deliberately insecure. The first step is to open the application’s source code (the main branch) in […]

This blog post is a text version of the demo provided during the Taint Analysis Livestream: Exploring Hidden Dangers In Your Team’s Code.
Table of Contents
Today, we’ll use WebGoat as our test application to demonstrate Qodana’s taint analysis functionality. This application is deliberately insecure. The first step is to open the application’s source code (the main branch) in IntelliJ IDEA (for this demo we are using 2025.1 Ultimate Edition). It is also required to configure your IDE to transform your IDE into the powerful SAST tool by installing the Security Analysis plugin and enabling the Security | Taint analysis inspection.
Then, navigate to the Security Analysis tab and run the analysis.
As you can see, we got the results immediately. Let’s take a look at them.
SQL injection
Here we have a classic example of SQL injection:
As we can see, the password field reaches the SQL statement without validation. Let’s quickly validate it via BurpSuite by breaking the SQL statement context:
The SQL syntax was broken, so the problem is indeed real. Now, it’s time to exploit it and get access to the account by making the WHERE clause true independent of the password’s correctness:
Now we should write a report to the team to notify them of the vulnerability. But how can we share our findings with the development team? Integrating the scan into the CI/CD process and having results in Qodana Cloud as a source of truth for the security and development teams is a good approach. Let’s see what this might look like.
Open the Qodana tab and click on the Try Locally button. For the purposes of this demonstration, I’ll use the default configuration with the qodana.starter profile and jetbrains/qodana-jvm:2025.1 linter.
It is possible to open the results locally in the browser by clicking on the Show Qodana in Browser button in the left-side panel:
Let’s filter the findings by the Security category and open the list of problem types that were found:
Now let’s find the SQLi problem that we analyzed:
When you perform this scan in Qodana Cloud, you can easily use the Copy link button and attach a link to the report so that the development team can easily find and fix the problem.
The proper mitigation in this case is to precompile the statement without user input and provide the values afterward. We can use AI Assistant to do this for us. Just select the line with the problem and ask AI Assistant to fix it:
And the problem is fixed correctly – the precompiled SQL statement doesn’t contain the unvalidated user input and it is not possible to escape from the SQL context.
Reflected XSS
Like many real applications, WebGoat has its own specificities and sometimes it is necessary to reconfigure the taint engine in order to spot the problems. There is a CrossSiteScriptingLesson5a class that was not detected by default. Let’s take a look and try to figure out why this happened.
The WebGoat application uses a custom AttackResultBuilder, an unsafe sink in this particular application. It’s not a library class or common approach that makes sense to support out of the box in the taint engine. But don’t worry, it’s possible to add this configuration to the special configuration file inside the inspections directory in the project root. Create this directory if you don’t already have it. Then select New | Custom Inspection from the context menu.
Select New Taint Configuration and provide any convenient name for the file:
Provide the following content for the configuration file:
sink(“org.owasp.webgoat.container.assignments.AttackResultBuilder.output”, listOf(1), TaintRule.XSS)
The final file content should appear as follows:
It is important to recompile the configuration by clicking the refresh button in the top left-hand corner:
Then the taint analysis will detect the problem in the editor on the fly:
Let’s analyze the data flow analysis trace:
There is a field field1 that contains the user input, and this will be reflected without proper validation. Let’s find this field on WebGoat’s web UI:
We can spot the message’s text inside the StringBuilder (“We have charged credit card…”), and we can now exploit it with a simple XSS payload :
Path traversal
It is also possible to find vulnerabilities in unexpected places. For example, a WebWolf application is required to help you solve tasks from the WebGoat. It isn’t designed to have vulnerabilities, but it nevertheless contains some of its own.
Here we have a path traversal vulnerability allowing us to write a file outside the designated directory.
Let’s save a file to the /tmp directory:
It is indeed an exploitable path traversal issue:
That’s all for the demo! As we demonstrated, taint analysis by Qodana is indeed capable of dealing with security issues. The number of sources and sinks is growing, so it detects more and more problems. Even if it can’t detect your specific sources or sinks, you can configure them via a convenient Kotlin DSL configuration format.
Want to see Qodana in action?
The Qodana team is here to show you how you can improve code quality and security. Let us know what your needs are and book a customized demo – or simply dive right in and try Qodana for yourself.