Welcome to part three of the blog series about Application Security Testing. In part one of this series, we looked at Static Application Security Testing (SAST) and in part two at Dynamic Application Security Testing (DAST). If you missed them, check them out here: Application Security Testing part 1 (SAST) and Application Security Testing part 2 (DAST). In this blog we are going to learn about Interactive Application Security Testing (IAST). First a brief explanation is given about IAST. Then there will be a short summary of advantages and disadvantages of IAST. Lastly, we will have some fun by trying out the IAST solution of Contrast Security against a vulnerable Java application.
Figure 1: IAST and other application security testing types during development phases
IAST works especially well when used together with integration or end-to-end tests, read during the testing phase of the pipeline. It is even possible to break the build if there are security vulnerabilities found or compare results from different environments.
Another possibility is to use IAST during local development. A developer gets real-time feedback when he or she is testing the application locally. This means that security vulnerabilities can be fixed even before a pull request is being initialized. Some vendors provide an IDE plugin that embeds a lightweight agent that brings the results straight into the IDE of the developer. In addition to the IDE plugin, some vendors also provide integration through build tools such as Gradle or Maven. This ensures that the IAST tool is always running where the application is deployed. It also means less configuration for individual developers because the integration only needs to be added once.
How does IAST work
Let’s discuss how Interactive Application Security Testing works from a high-level perspective. An IAST tool is a product that uses instrumentation to assess an application for security vulnerabilities. In this case instrumentation means adding code to an application at runtime with the purpose of monitoring the behavior of the application against a set of security rules. This is done via an agent. The agent must be loaded together with your application. Once loaded, the interactions in the application will be continuously analyzed. It will give real time feedback about vulnerabilities and makes them available in the IAST security dashboard. It does not matter how these interactions are triggered. It could be a human that is manually testing the application or an automated process that runs functional tests against the application. It is not necessary to use malicious payloads when performing the tests. If you want to learn more about instrumentation in Java, checkout: Java Instrumentation.
Figure 2: high level overview of IAST
Advantages & disadvantages of IAST
- Detects runtime security issues in real-time by analyzing application behavior at runtime
- Fast – analysis and results provided in real time as the application is tested
- Comprehensive results from URL/parameter entry point to line of source code, and full dataflow analysis
- Significantly lower rate of false positives (For example: Contrast Security scores 100% accuracy on the independent OWASP Benchmark, compared to the best SAST tool which scores 55%)
- Insight into test coverage highlights endpoints and routes that require additional tests.
- Easy to scale because it requires no special expertise
- Native support for integration with third parties such as SIEM tools, tracking tools, chat tools and more plus provides a nice API
- Can be used early in the software development lifecycle but you will need to be able to deploy a running application with the IAST agent somewhere (local or test server)
- Aligns security and QA because IAST tool provides insights into the test coverage of the application.
- Like static application security testing (SAST), IAST is also programming language specific. Not every vendor might support your stack
- Coverage depends on completeness of manual or automated functional tests (do they hit all the relevant endpoints of the web application with interactions)
- Commercial tools with proprietary software means dependent on supplier for new security rules
- The agent adds a small risk comparable to adding a library. Similar to application performance monitoring and observability tools.
- Client-side code is not scanned for vulnerabilities. Nevertheless, IAST does check if untrusted input ends up in client-side code.
- Like Static application security testing: changes to HTTP requests by intermediate controls are not detected. For example: stripping or adding of headers by a reverse proxy. This also applies to Dynamic Application Security Testing if testing takes place directly on the application (for example: a test environment that has no reverse proxies in place).
When you look at the above, there seem to be some disadvantages. They are listed to make you aware of the fact that you should fine tune the tool and the process around it. They can be overcome by taking measures to counter them. For example, by researching which IAST tools supports your stack, the first disadvantage is mitigated.
Demo with Contrast Assess Community Edition
In this part we will test the vulnerable Java web application with a IAST tool by Contrast Security called Contrast Assess. This tool is part of the Contrast Security suite that also offers the following application security testing tools: Static Application Security Testing (SAST), Software Composition Analysis (SCA), Runtime Application Self Protection (RASP) and a Serverless security scanner. We will look at their SCA solution in a later blog. If you are also interested in their SAST solution, you can try it out for free here: Contrast Scan. I chose Contrast Assess because it has a free community edition and I like their platform. I also made a video tutorial for the first part of the demo, you can find it here: tutorial.
It is time to get practical. Like I mentioned before, we are going to scan a vulnerable Java web application. You can download the source code here: vulnerable web app
- First download the vulnerable web application to a folder of your choosing.
- Startup a terminal and navigate to the root folder of the vulnerable web application.
- Download the latest version of the Contrast Security Java Agent by using this command in the terminal curl -L https://repo1.maven.org/maven2/com/contrastsecurity/contrast-agent/5.1.0/contrast-agent-5.1.0.jar -o contrast-agent.jar and keep the terminal open. If the curl command does not work, check the latest version in maven and replace the version number (made bold) in the URL.
The next step is to register an account at Contrast Security for access to the community edition.
- Open a browser and enter the following URL: https://www.contrastsecurity.com/contrast-community-edition . At the bottom of the page you can create an account.
- Once you entered your details, you will receive an e-mail with a link to set your password. Set your password and agree with the terms.
- Login at https://ce.contrastsecurity.com/Contrast/static/ng/index.html#/pages/signin with your e-mail address and password.
- Click on the “Get Started” and then accept the terms and click on the “Next” button. Now click on the “Start Agent Setup” button.
- You don’t have to choose an agent because we downloaded it before. The only thing you need is the configuration file. Click on “Download the Java contrast_security.yaml” and store the file in the root directory of the vulnerable web application.
- Click on the “Close” button
Return to the open terminal window which should display the root folder of the vulnerable web application. It is time to start the application together with the agent. Make sure you have Java 17 or lower installed. You can download Java here: Java. Run the following command in the terminal: java -javaagent:./contrast.jar -Dcontrast.config.path=contrast_security.yaml -jar vulnapp-0.0.1-SNAPSHOT.jar
Open the browser and navigate to http://localhost:8080 and start navigating the different pages of the web application. Register a user, login to the application, post a message, view a message, logout etc… The Contrast Agent will analyze the web application in the background and sends any found vulnerabilities to the Contrast Security Dashboard.
Results of Contrast Assess
Let’s login at https://ce.contrastsecurity.com/Contrast/static/ng/index.html#/pages/signin . Once logged in click on “Applications” and the name of the vulnerable application we just tested. In the overview of the application, we can see that it was given a risk score of D by Contrast. This is quite bad since A is the highest rating and F the lowest. The score is based on vulnerabilities that were found in the custom code and libraries of the application. For now, we will focus on the custom code. The library findings will be discussed in the next blog. Click on “Vulnerabilities”.
You will see an overview of all the vulnerabilities that Contrast Assess found. My results are displayed by figure 3. A small side note: not all rules are activated in the community edition of Contrast Assess. Of the available 49 rules, 37 are active. In other words, 12 rules are not activated. You can find the rules in “Policy” tab of the vulnerable web application overview.
Figure 3: Contrast Assess results for vulnerable web application
Contrast Assess found 7 vulnerabilities. We will focus on the critical findings for the sake of time. It found two critical vulnerabilities. Both are “SQL Injections”. The “SQL Injection” in the /login page was also found by ZAP. The “SQL Injection” in the /posts page was found by Semgrep.
Since we already discussed the “SQL Injection” in the /posts page in the first blog about SAST. We will discuss the “SQL Injection” in the /login page which was briefly mentioned during the second blog about DAST.
If we click on the “SQL Injection from "email" Parameter, "password" Parameter on "/login" page” on the vulnerabilities page of the vulnerable web application an overview page of the vulnerability is shown. The same overview that is displayed by figure 4.
Figure 4: overview of /login “SQL Injection” vulnerability
The overview shows that the parameters password and email ended up in a database query via line 24 in the UserRepositoryImpl class. It also explains what the risk of “SQL Injection” entails. If you want more details, click on the “Details” tab. The “HTTP Info” tab shows the HTTP request that triggers the vulnerability. The “How to Fix” tab gives us information about how we can prevent “SQL Injection” from happening. The advice is to use ‘CallableStatement’ for stored procedures and ‘PreparedStatement’ for normal queries. In our case we should use a ‘PreparedStatement’ since we are not using a stored procedure.
Let’s have a look at the code:
Figure 5: Vulnerable code - “SQL Injection” /login
At line 24 a String called “myCustomComplicatedQuery” is passed to a Query object called “nativeQuery”, which is then used to fetch results from the database. In this case we are using the Java Persistence API in an unsafe manner because we concatenate unvalidated user input into the ‘String’ called “myCustomComplicatedQuery” and use that String directly to create a “Native Query” with the ‘EntityManager’. This “Native Query” is used by ‘EntityManager’ to fetch results from the database.
To fix this we should modify the code to use a ‘PreparedStatement’. Instead of sending a SQL query that embeds user input, which makes it impossible for the database to distinguish between the SQL query and user input. A SQL query with placeholders in the form of question marks is used. The SQL query with placeholders is pre-compiled by the database. This makes it possible for the database to make a distinction between the query and user parameters. Later in the process of fetching the data from the database, the placeholders are replaced by the user input. This prevents “SQL Injection” or in other words manipulation of SQL queries.
We can implement a ‘PreparedStatement’ for the Java Persistence API like this:
Figure 6: Fixed code - “SQL Injection” /login
If you want to test if the vulnerability is remediated. Go back to the Contrast Security dashboard an delete the SQL injection finding. Restart the application with agent and login again. This time the SQL injection is not found. Which means the above fix worked as intended. The enterprise edition of Contrast has this as a feature and automatically marks vulnerability as remediated when the agent detects that the vulnerability has been fixed during subsequent builds/test runs.
Next to Contrast Assess, we also get a preview of what Contrast Protect (the Runtime Application Self Protection (RASP) solution) can do. Contrast Protect can block attacks. This behavior can be enabled by toggling protection on in the “Policy” tab. In the community edition it can be enabled for multiple environments: “Development”, “QA” and “Production”. Make sure the “Protect” mode is enabled for the “Cross Site Scripting” rule for the “Development” environment. It should have the status “Block”.
On a side note: the Contrast agent can be configured to run in “Assess” or “Protect” mode. Technically the agent behaves different depending on the mode it runs in, in “Protect” mode it must be more performant since it normally runs in a production environment. This is why it is required to restart the application with the agent when switching between “Assess” and “Protect” mode.
Figure 7: Some of Contrast Security protect rules
While it did not find the Cross Site Scripting attack that OWASP ZAP did find, it will block the attack because protect is enabled by default. Try entering the payload <script>alert(‘xss’)</script> in the form at http://localhost:8080/posts?postId=1. You will get an error page. When you look at the logging of the web application in the terminal where you started the application, you will see an AttackBlockedException. This Exception is triggered by the Contrast Security agent. In other words, the Contrast Security agent provides input validation against Cross Site Scripting attacks in “Protect mode”. Even though you will not be aware of the XSS vulnerability perse at least you will be ware of the fact that input validation is missing.
The fact that Contrast Assess missed this “Persistent Cross Site Scripting” (also known as “Stored Cross Site Scripting”) vulnerability is the consequence of how the internals of the agent work and that it is fine-tuned to prevent false positivies. However it is possible to add support for additional type of vulnerabilities by using a canary value. Contrast describes this as “A value that will be fed by attack testing tools in order to test stored XSS or other second-order injection attacks to be detected coming out of databases“. We can add a canary value by adding the following to the command that starts the agent and application: -Dcontrast.assess.second_order_canary=<payload>
Normally Contrast Assess does not require malicious payloads to find vulnerabilities. When we use canaries you do need to use the value (<payload> part of command above) your entered with ‘-Dcontrast.assess.second_order_canary’ to find the vulnerability. From the outside it looks more like a traditional DAST scanner, but this is not the case. I still looks at the internal dataflow of the application instead of HTTP Requests and Responses.
Let’s detect the “Persistent Cross Site Scripting” vulnerability. Start the application and agent via the terminal with the following command:
java -javaagent:../contrast/contrast.jar -Dcontrast.config.path=../contrast/contrast_security.yaml -Dcontrast.assess.second_order_canary="<script>alert('xss')</script>" -jar vulnapp-0.0.1-SNAPSHOT.jar
First we need to disable the protection feature for the vulnerable web application. Go to the policy page of the vulnerable web application by clicking on the vulnerable application in the Contrast Security dashboard. Click on the “Policy” tab and then the “PROTECT” tab. Use the dropdown button of Cross Site Scripting rule and set it to “OFF” for all three environments. Now protection for Cross Site Scripting is deactivated.
We will register a new user to demonstrate Contrast Assess only creates a finding for script tags that are not output encoded. Browse to http://localhost:8080/register. Register any “E-mail Address” or “Password” you want, but use the payload <script>alert(’xss')</script> as full name. Now login as the user you just created. Notice that the page shows the text “Welcome to your homepage, <script>alert('xss')</script>!”. There is no problem here because the <script>alert(’xss')</script> is output encoded. Now navigate to the Contrast Security dashboard at https://ce.contrastsecurity.com/Contrast/static/ng/index.html#/pages/signin and look at the vulnerabilities of the vulnerable web applications. There are no new findings. So eventhough we used the payload <script>alert(’xss')</script> which is identical to the canary value, Contrast Assess understands that it is not an issue in this instance.
Now navigate to http://localhost:8080/posts?postId=1 via the browser. Create a new post via the form with the text <script>alert(1)</script>. Go back to the Contrast Security Dashboard and notice that there are no new findings. Contrast Assess does not detect it because the payload differs from the one we used as the canary value.
Let’s try again. Create a new post with the text <script>alert(’xss')</script> and return to the Contrast Security dashboard at https://ce.contrastsecurity.com/Contrast/static/ng/index.html#/pages/signin. Now Contrast Assess did find the “Persistent Cross Site Scripting” vulnerability as shown in figure 7:
Figure 8: Contrast Security Dashboard results include Stored Cross Site Scripting
Do notice that unlike OWASP ZAP (the DAST tool we used in the second blog of this series), Contrast Assess did not report the false positive “Reflected Cross Site Scripting”. When you look at the details of the “Persistent Cross Site Scripting” vulnerablity, you will not find the exact location of the problem: the line of code in the posts.html template that is responsible for the vulnerablity (explaind in part 2 of this blog series). But it does give you more relevant information then OWASP ZAP. OWASP ZAP only gives the location of the vulnerable endpoint. Contrast Assess also lets you know that a write function was called without prior validation and encoding by a class of Thymeleaf as is shown by figure 9.
Figure 9: Details about “Persistent Cross Site Scripting” Vulnerablity and call by Thymeleaf
Remember: when you use canary values, make sure that your manual or automated tests contain the same values.
Do realize that we used the community edition and the full edition has more features and security rules. This is blog is about introducing you to Interactive Application Security Testing. I am planning to write a blog about the Contrast Security platform in the near future. So also stay tuned for that.
This concludes the blog about Interactive Application Security Testing. In the next one we will look at Software Composition Analysis and secret scanning. See you at the next one!