Testing the actual security of the most insecure Docker application
JFrog Advanced Security series: Analyzing the exploitability of third party vulnerabilities, on the most insecure Docker application - WebGoat.
Our previous research on CVE exploitability in the top DockerHub images discovered that 78% of the reported CVEs were actually not exploitable. This time, the JFrog Security Research team used JFrog Xray’s Contextual Analysis feature, automatically analyzing the applicability of reported CVEs, to scan OWASP WebGoat – a deliberately insecure application.
The results identified that out of 60 CVEs reported with a Critical CVSS score, only 10 are actually applicable.
WebGoat critical CVEs by Contextual Analysis scan results
Learn More About Advanced Security
This blog post will provide detailed applicability analysis of the notable critical CVEs as reported by Contextual Analysis, and offer insights for reducing the number of CVE false positives.
- Research methodology
- JFrog Xray scan results
- Analyzing the CVEs reported as applicable
- Analyzing the CVEs reported as not applicable
- Contextual Analysis With JFrog Advanced Security
WebGoat is an insecure web application, written mostly in Java, used publicly for application security training and tools benchmarking. The WebGoat Docker image is a well-chosen case for our research and for showing how powerful Contextual Analysis is when it comes to spotting the actual exploitable vulnerabilities and filtering out the ones that are not exploitable. The combination of popular 3rd party components and synthetic 1st party insecure flaws makes it a great target for testing. As this image is a synthetic insecure application, we could also use the official documentation of the planted vulnerabilities, which we can compare to, as ground truth, and even find more exploitable vulnerabilities that were not planted on purpose and are not documented.
WebGoat image, Dockerhub
Our research methodology
In this research, we set out to find which CVEs are actually exploitable in a highly vulnerable application such as WebGoat. Although we are always interested in a wide range of exploitability testing, for the purpose of this blog post we’ll focus only on the vulnerabilities with critical CVSS score.
After selecting our target application, WebGoat, the next step was scanning it using JFrog Xray with the Contextual Analysis feature enabled, to determine which of the reported CVEs are really exploitable.
The final step in our research was to further investigate the results provided by Xray’s Contextual Analysis functionality. The Contextual Analysis scan results consider exploitability factors such as code prerequisites, configuration prerequisites, and running environment, to determine whether a CVE is exploitable or not.
As in our previous research, we expected most of the reported CVEs to be unexploitable. This is because in most cases, even though a vulnerability was reported because “package X is installed”, for the vulnerability to be exploitable, some factors and prerequisites (code, configuration, or environment) that are crucial for exploitation, actually don’t exist in the “vulnerable” application.
JFrog Xray scan results
After scanning the WebGoat Docker image with JFrog Xray’s Contextual Analysis, we discovered that out of 60 CVEs reported with a Critical CVSS score, only 10 are actually applicable.
These scan results help us stay focused in our research on the CVEs that are most likely to be exploitable, and demonstrate how Contextual Analysis can help security teams to prioritize fixing the applicable CVEs and deprioritize handling CVEs that are actually not applicable.
Let’s examine the applicability conditions of the CVEs using the Contextual Analysis results.
Analyzing the CVEs reported as applicable
We started by analyzing the 10 critical CVEs that were reported as applicable by the Contextual Analysis results. The exploitability conditions for these 10 CVEs are confirmed by Contextual Analysis in this Docker image. This means that they are most likely to be targeted and exploited by black hat hackers, in the same way as we’re doing in this research as white hat hackers. Below is the analysis of these applicable CVEs.
The first notable reported CVE is a command injection in XStream for Java, which allows for remote code execution when deserializing crafted XML or JSON data. In order to exploit this vulnerability, an attacker must be able to supply arbitrary input to the `xstream.fromXML()` function.
As mentioned above, an installation of XStream in the vulnerable version is not enough for the successful exploitation of this vulnerability. The Contextual Analysis scan results of the WebGoat image help us understand whether this vulnerability is contextually applicable. An applicable result from Contextual Analysis means that there is a vulnerable use of XStream in the application, or in other words, the vulnerable function `fromXML()` is called with external input. As the results show, this vulnerability is applicable and therefore should be treated as a serious issue that may be exploited by attackers.
JFrog Xray Information for CVE-2013-7285
The following shows the Contextual Analysis breakdown:
JFrog Xray Contextual analysis for CVE-2013-7285
Using the Contextual Analysis results, we can see that a vulnerable call to `fromXML()` was found with external input to its first argument. Here is this vulnerable use of `xstream.fromXML()` as can be seen in WebGoat source code:
Vulnerable use of `fromXML()` in WebGoat, Github
In our research, we successfully exploited this vulnerability by passing a malicious deserialized object as a parameter to this function and performing remote code execution.
It is important to note that this vulnerability was planted in the WebGoat application for training purposes, as part of the vulnerable components section. In a real-world application, the vulnerable use case is exactly the same while the typical difference is the way user input propagates to the vulnerable call.
Xstream exploitation as part of WebGoat training
Furthermore, Xray results show a few more Xstream CVEs related to the same Xstream version. These CVEs were not documented in the WebGoat project. Using Contextual Analysis, we also successfully detected and exploited the following critical vulnerabilities:
The last notable reported CVE is the famous SpringShell – a class loader vulnerability in Spring Web that leads to remote code execution. In order to exploit this vulnerability, an attacker must find an exposed web endpoint that binds request parameters to POJOs (Plain Old Java Objects).
This vulnerability lies in the Spring Framework “data binding” mechanism. This mechanism takes parameters from the request URL or request body, and assigns them to function arguments or in some cases into Java objects.
When assigning request parameters to Java objects, there is a security risk since some “internal” parameters of the built object should never be externally controlled (like `Class`, `ClassLoader` and `ProtectionDomain`). Spring contains specific code that denies attackers from assigning to these internal attributes.
Unfortunately, starting from Java 9, due to an introduction of a new API (`class.getModule`) it is possible to bypass Spring’s protection and assign arbitrary values to properties of the `ClassLoader` attribute.
Let’s take a look at the Contextual Analysis results of this vulnerability when we scanned the WebGoat Docker image:
JFrog Xray Information for CVE-2022-22965
An applicable result from Contextual Analysis means that there is a vulnerable use of Spring Framework “data binding” mechanism in the application, or in other words, a function with a vulnerable annotation (e.g. `@GetMapping`) that accepts simple java class argument is defined.
Let’s see the Contextual Analysis breakdown:
JFrog Xray Contextual Analysis for CVE-2022-22965
As we can see, Contextual Analysis provides all the locations within WebGoat.jar that use Spring Framework “data binding” mechanism in a vulnerable way.
JFrog Xray Scanner Explanation for CVE-2022-22965
Here is one of the above detected vulnerable data binding functionalities from WebGoat source code:
Vulnerable POJO data binding functionality to `UserForm` object. (From WebGoat Github)
Vulnerable POJO data binding functionality to `UserForm` object. (From WebGoat Github)
As for exploiting this vulnerability – the original published exploit for this vulnerability aimed for Apache Tomcat, and several other exploits were also published for more web applications such as Payara and Glassfish. In the WebGoat image that we scanned, the vulnerable web server is actually Undertow. While there is no published exploit for Undertow to date, it is likely to assume that attackers would be able to develop a working exploit for this case, as the applicability conditions contextually apply as demonstrated above. Thus, we consider this vulnerability exploitable and should be treated as a serious issue accordingly.
Analyzing the CVEs reported as not applicable
As demonstrated before, JFrog’s Contextual Analysis provides the ability to determine whether a vulnerability is exploitable in the context of an application. Contextual scanners run on their most conservative setting, which allows applicability detection with extremely high confidence for vulnerabilities tagged as not applicable.
The ability to automatically reduce the number of vulnerabilities needed to be examined is a game changer. This ability helps security engineers to prioritize and even ignore vulnerabilities based on their exploitability and not just their severity.
Let’s examine this further.
In total, 35 CVEs were reported by Contextual Analysis as not applicable:
|CVE ID||COMPONENT||Why the CVE Not Applicable
(Contextual Analysis Result)
|CVE-2016-1000027||spring-web||The vulnerable class (Simple)HttpInvokerServiceExporter is never instantiated|
|CVE-2017-11462||krb5||No references to the vulnerable functions of gssapi were found|
|CVE-2017-12652||libpng||No references to the vulnerable functions were found|
|CVE-2017-14062||libpng||No references to the vulnerable functions were found|
|CVE-2017-15088||krb5||No references to the vulnerable functions were found|
|CVE-2017-15670||libc6||The vulnerable function glob/glob64 is never called|
|CVE-2017-15804||libc6||The vulnerable function glob/glob64 is never called|
|CVE-2017-18269||libc6||The vulnerable function memmove is never called|
|CVE-2018-11236||libc6||The vulnerable function realpath is never called|
|CVE-2018-6485||libc6||No references to the vulnerable functions were found|
|CVE-2018-6551||libc6||No references to the vulnerable functions were found|
|CVE-2019-12900||libbzip2||The vulnerable function BZ2_bzDecompress is never called|
|CVE-2019-20367||libbsd||The vulnerable function nlist is never called|
|CVE-2019-8457||sqlite3||The vulnerable module rtree is not enabled|
|CVE-2019-9169||libc6||No references to the vulnerable functions were found|
|CVE-2020-10683||dom4j||No references to the vulnerable functions were found|
|CVE-2020-11656||sqlite3||The vulnerable module SQLITE_DEBUG is not enabled|
|CVE-2020-1745||undertow-core||AJP connector is not enabled in Undertow’s configuration|
|CVE-2021-33574||glibc||The vulnerable function mq_notify is never called|
|CVE-2021-3520||liblz4||The vulnerable function LZ4_decompress_safe_partial is never called|
|CVE-2021-35942||glibc||The vulnerable function wordexp is never called|
|CVE-2022-1471||snakeyaml||The vulnerable function Yaml.load is not called|
|CVE-2022-21724||postgresql||The vulnerable function DriverManager.getConnection is never called with external input|
|CVE-2022-22822||libexpat||No references to the vulnerable functions were found|
|CVE-2022-22823||libexpat||No references to the vulnerable functions were found|
|CVE-2022-22824||libexpat||No references to the vulnerable functions were found|
|CVE-2022-22978||spring-security||No references to the vulnerable functions were found|
|CVE-2022-23218||glibc||The vulnerable function svcunix_create is never called|
|CVE-2022-23219||glibc||The vulnerable function clnt_create is never called|
|CVE-2022-23852||libexpat||No references to the vulnerable functions were found|
|CVE-2022-25235||libexpat||No references to the vulnerable functions were found|
|CVE-2022-25236||libexpat||No references to the vulnerable functions were found|
|CVE-2022-25315||libexpat||No references to the vulnerable functions were found|
|CVE-2022-26520||postgresql||The vulnerable functions setLoggerFile, setUrl, setURL, setProperty, connect, getConnection are never called with external input|
|CVE-2022-27404||libfreetype||No references to the vulnerable functions were found|
Let’s examine 2 examples from the above list:
The first CVE is an insufficient input validation in PostgreSQL. This vulnerability allows a remote attacker to cause insecure deserialization. In order to exploit this vulnerability, an attacker needs to supply a malicious class to the vulnerable function `DriverManager.getConnection()`. In other words, the application must use PgJDBC in a vulnerable manner, and pass uncontrolled input to the vulnerable function `DriverManager.getConnection()`.
JFrog Xray Information for CVE-2022-21724
The contextual scanner for this vulnerability, checks for `getConnection()` calls with uncontrolled input. No vulnerable use of PgJDBC means this vulnerability is not exploitable.
JFrog Xray Contextual Analysis for CVE-2022-21724
The second CVE is an integer overflow in xmlparse.c in libexpat. This vulnerability allows a remote attacker to possibly cause an unspecified impact. In order to exploit this vulnerability, a code that uses the library in a vulnerable manner (interact with libexpat vulnerable APIs) must exist in the system.
JFrog Xray information for CVE-2022-23852, Xray
The contextual scanner for this vulnerability, checks for any 1st party binary that uses libexpat’s vulnerable APIs (XML_GetBuffer, XML_Parse). Thus, no use of these vulnerable APIs means this vulnerability is not exploitable.
JFrog Xray Contextual Analysis for CVE-2022-23852
Many CVEs turned out to be not applicable. Does this mean that this “deliberately insecure application” is secured after all?
The scan results above show that only 10/60 critical CVEs that were contextually analyzed are actually applicable. This can be quite surprising considering that WebGoat is an application that was built insecurely on purpose. We might expect a synthetic vulnerable application to have an extremely large number of exploitable CVEs. In fact, these findings are aligned with what we know so far about CVEs – in 2023, in most common cases, the applicability conditions for exploiting the CVEs are not met.
The first reason for finding this many unexploitable critical CVEs is that WebGoat is designed to contain insecure logical flaws in the application’s 1st party code and not security issues caused by 3rd party vulnerable components. Thus, the number of exploitable CVEs, and the potentially exploitable CVEs, is not affected by the fact that WebGoat is a vulnerable application.
Moreover, as we know, the existence of a vulnerable component in WebGoat, like in any other application, is not enough for a vulnerability to be exploited. Additional parameters such as configurations, running environments, and how the application uses the vulnerable component are the most influential factors of vulnerable component exploitability. Therefore, although there is a large number of CVEs and vulnerable components, just a few of them are actually exploitable. The authors of WebGoat simply didn’t plant the vulnerable conditions, like the usage of vulnerable third-party functions, nor configured the system to execute a vulnerable component.
Why were undocumented exploitable CVEs found?
The above Contextual Analysis results reported CVEs that were not even documented as known security issues in the training section of the WebGoat project (see the list above of Xstream CVEs). The existence of unknown exploitable vulnerabilities in a deliberately insecure application might be ironic but in fact makes perfect sense, because even though an insecure application is being developed, it will always have more unknown security issues, especially in the world of 3rd party CVEs when new vulnerabilities are constantly being disclosed. This emphasizes the importance of integrating security as part of the development and CI/CD processes, with automated tools and automatically analyzing the applicability of the reported CVEs on the final product.
Contextual Analysis With JFrog Advanced Security
This research was powered by the new “Contextual Analysis” feature which is included in the recently announced JFrog Advanced Security set of capabilities for JFrog Xray. This release takes JFrog Xray out of its familiar software composition analysis space and into the realm of advanced software supply chain security.
Contextual Analysis uses the context of the artifact to identify whether vulnerabilities are applicable or not. This process involves running automated contextual scanners on the container image to determine reachable paths and the configuration settings for the analyzed vulnerabilities. Xray automatically validates high and very high impact vulnerabilities, such as those that have prerequisites for exploitations, and provides contextual analysis information to assist in figuring out which ones are applicable or not. This saves developers from a lot of wasted time and effort.
- Save developer time by only remediating vulnerabilities that are applicable
- Analyze the finished code (binary) the same way an attacker would
- Know which CVEs are exploitable and their potential impact
- Test a vulnerability in the context of the complete artifact, build or Release Bundle
- Enable action and remediation in the context of the artifact, build or Release Bundle