Introduction

Recently researcher Steven Seeley discovered a way to abuse the popular Apache Struts frameworks’ file upload functionality to achieve remote code execution. This bug, known as CVE-2023-50164, has been assigned a 9.8 CVSS score. No doubt this is causing some security practitioners to have flashbacks of the “good times” that a serious Struts bug can cause, like CVE-2017-5638 which rampaged through any organization that didn’t patch.

However, despite these apparent similarities this is where the comparisons end; unlike CVE-2017-5638, an OGNL expression injection vulnerability through a malicious value in the Content-Type header within the FileUploadInterceptor middleware, the exploitation of CVE-2023-50164 involves several preconditions that are dependent on the behavior and implementation of the application using Apache Struts. While CVE-2023-50164 is a serious issue and developers should promptly update applications using vulnerable versions of Apache Struts, it will be very difficult for an attacker to scan for and exploit this vulnerability at scale in the same manner as CVE-2017-5638.

What is CVE-2023-50164

As described in 孤*y’s excellent blog post, the Struts ActionSupport class contains a bug in the filename parameter filtering in the file upload implementation. The blog explains the technical requirements and details for successful exploitation of the vulnerability; please refer to it for a more in depth explanation.

The Apache Struts vulnerability is essentially caused by parameter confusion, where an attacker can first capitalize a parameter in the request and then submit an additional parameter (in lowercase) that overrides an internal file name variable. Because of Apache Strut’s internal processing logic, when a class extending or implementing “ActionSupport” receives the arguments from the HTTP Request, the poisoned filename value can contain path traversal characters. The bug bypasses Apache Strut’s getCanonicalName (in AbstractMultiPartRequest.java) to leave the path traversal payload in the final filename. This behavior potentially turns any server using the ActionSupport class (or extending it) into a mechanism for attackers to achieve arbitrary file write on the server.

Arbitrary file write on a Struts Java server gives the attacker the ability to write a server-side rendered file, such as a JSP file, into a target directory. When the attacker then requests the file from the server the JSP payload is executed and the attacker has compromised the server. The JSP code execution method through file write is why CVE-2023-50164 has been given a critical CVSS value.

The proof of concept included in 孤*y’s blog post is very straightforward and easy to reproduce, which means that proof of concept scripts will likely be released soon.

Example Exploitation from 孤*y’s blog post

Mitigating Factors

While the bug can result in remote code execution, there are constraints that restrict where exploitation might occur. These constraints are as follows:

  1. The application must use the Struts ActionSupport class in some capacity, like in the example Struts file upload application. If a grep of the codebase does not find “ActionSupport” anywhere, the application is likely not affected by this bug. Developers should verify that any file upload functionality in the application doesn’t rely on a library that ultimately uses ActionSupport either.
  2. If the application does use ActionSupport somehow, the functionality must be exposed without authentication to the internet for an unauthenticated attacker to potentially exploit the vulnerability. Mass internet scanning for this vulnerability is going to require that any ActionSupport endpoints are unauthenticated. Authenticated users might also be a threat, so if the application exposes file upload to authenticated users, be aware that the vulnerability might still apply.
  3. Even if both factors 1 and 2 are true, the application also needs to have extended ActionSupport without performing any additional input sanitization of the arguments. Because the vulnerability only modifies the incoming arguments, if the application does further sanitization of the filename, then the vulnerability will likely not apply. Alternatively, some applications may not leverage the user-supplied filename when writing files to disk and could instead, for example, leverage a randomized filename or hash of the input filename for the file name. In such a case, the vulnerability would also not be exploitable.
  4. Even if none of the above are true, many WAFs will not allow a slew of ../’s through to the backend application server.
  5. The application server implementing the server side upload logic needs to upload the file to the local filesystem of the webserver and have write permissions to a sensitive directory that would be useful to an attacker such as the webroot to upload a JSP webshell. In scenarios where the backend datastore used for the file upload is something like Amazon S3 the risk of more serious issues, such as remote code execution, are much lower.

We believe that in most scenarios, due to the preconditions listed previously, that most instances of exploitation of CVE-2023-50164 will be more one-off custom attacks against impacted applications meeting the required preconditions versus indiscriminate mass-exploitation attempts.

However, while the risk of exploitation is much lower than prior vulnerabilities in Apache Struts, we still recommend that application developers running the impact version of Apache Struts promptly upload to the latest version even in scenarios where the necessary preconditions for exploitability are unmet.

Conclusion

While CVE-2023-50164 is a serious security vulnerability, it is going to be difficult for attackers to perform mass scanning and exploitation of this vulnerability. The numerous preconditions required to exploit the issue along with the requirement for an application-defined file upload endpoint to be accessible makes mass exploitation a challenge. This bug is serious and deserving of its CVSS score of 9.8 – however, it’s also a good reminder that CVSS scores don’t directly represent risk of exploitation. The numerous preconditions required make this vulnerability harder to identify automatically, and harder to exploit reliably. Nevertheless, we recommend mitigation of this issue as soon as possible.