CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Dashboard
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2017-5638
9.894.27%

The Equifax Breaker: Deep Dive into CVE-2017-5638

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 25, 2026·5 min read·9 visits

Active ExploitationCISA KEV ListedRansomware Use

Executive Summary (TL;DR)

Critical Remote Code Execution (RCE) in Apache Struts 2 via the Jakarta Multipart parser. Attackers can execute arbitrary system commands by sending a malicious OGNL expression in the 'Content-Type' HTTP header. No authentication is required.

In the annals of cybersecurity history, few vulnerabilities have caused as much chaos, financial ruin, and executive sweating as CVE-2017-5638. It is the perfect storm: a widely used enterprise framework (Apache Struts 2), a trivial exploitation vector (an HTTP header), and a root cause rooted in over-helpful error handling. This vulnerability famously facilitated the 2017 Equifax data breach, exposing the personal information of 147 million people. It serves as a stark reminder that even the most robust fortresses can be toppled if the doorman decides to execute instructions scribbled on a suspicious package.

The Hook: When Error Messages Attack

Imagine you're a bouncer at a club. Someone tries to hand you a fake ID. Instead of just saying "Access Denied," you read the name on the ID out loud over the club's PA system. Now imagine the name on the ID isn't a name, but a magic spell that causes the club to explode.

That is essentially CVE-2017-5638. Apache Struts 2, a heavy-lifting framework for Java web applications, uses the Jakarta Multipart parser to handle file uploads. When a user tries to upload a file, they send a multipart/form-data request. If the request is malformed—say, the Content-Type header is garbage—the parser throws an exception.

The framework, trying to be helpful, catches this exception and attempts to generate a localized error message to send back to the user. The problem? It includes the raw content of the invalid header in the error message processing pipeline. And in Struts 2, that pipeline processes OGNL (Object-Graph Navigation Language).

This means if an attacker puts an OGNL payload in the Content-Type header, Struts doesn't just reject it; it executes it while trying to tell you it's invalid.

The Flaw: Recursion is the Devil's Playground

Let's dig into the JakartaMultiPartRequest.java class. When an upload error occurs (like an invalid Content-Type), the code calls buildErrorMessage. This method eventually calls LocalizedTextUtil.findText.

Here is the logic flow of the failure:

The fatal flaw lies in how findText was called. The developers passed the exception message (which contains the attacker's string) as the default message key. The Struts localization system is designed to parse OGNL expressions in message keys to allow for dynamic text generation. By passing untrusted input into a function designed to evaluate expressions, Struts effectively handed the keys to the kingdom to anyone with curl.

The Code: The Smoking Gun

The fix was painfully simple, which makes the exploit even more tragic. The vulnerability existed because the exception message e.getMessage() was passed as the 4th argument to findText.

Vulnerable Code (Before):

// The 'e.getMessage()' is passed as the default message key
// If the key isn't found, Struts evaluates this string for OGNL.
return LocalizedTextUtil.findText(
    this.getClass(), 
    errorKey, 
    defaultLocale, 
    e.getMessage(), // <--- THE KILL ZONE
    args
);

Patched Code (After):

// First, check if the errorKey exists.
if (LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, new Object[0]) == null) {
    // If not, use a safe default key and pass the exception message as an ARGUMENT
    return LocalizedTextUtil.findText(
        this.getClass(), 
        "struts.messages.error.uploading", 
        defaultLocale, 
        null, 
        new Object[] { e.getMessage() } // <--- Safe as an argument
    );
} else {
    return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, args);
}

In the patched version, the dangerous string e.getMessage() is wrapped in an Object[] array and passed as an argument. Arguments are treated as literal strings and are not recursively evaluated for OGNL expressions. It's the difference between eval(input) and print(input).

The Exploit: Bypassing the Sandbox

Struts 2 has security mechanisms to prevent OGNL from doing dangerous things, like accessing static methods or modifying system properties. However, OGNL is incredibly flexible. The exploit payload for CVE-2017-5638 is a masterclass in sandbox evasion.

The payload typically looks like this (formatted for readability):

%{
  (#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).
  (#process=@java.lang.Runtime@getRuntime().exec('cat /etc/passwd')).
  (#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).
  (@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).
  (#ros.flush())
}

Wait, it's not that simple. By Struts 2.3.x, strict OGNL security was in place. Attackers had to explicitly overwrite the _memberAccess object to regain access to private members and static methods.

The "Universal" Payload: Attackers set Content-Type to a massive string starting with: %{(#_='multipart/form-data')...

They use reflection to reset #_memberAccess to DEFAULT_MEMBER_ACCESS (which allows everything). Once they have that, they can instantiate java.lang.ProcessBuilder. Because this happens before the request is fully processed or logged by the application logic, standard application logs often show nothing until it's too late.

The Impact: Why We Should Panic

This is a System-Level RCE. It doesn't get worse than this. The application server (likely Tomcat or JBoss) is usually running with significant privileges.

  1. Data Exfiltration: The Equifax breach proved this. Attackers didn't just crash the server; they queried databases and exfiltrated PII for months.
  2. Lateral Movement: Once inside the web server, attackers are behind the firewall. They can pivot to internal databases, backend services, and domain controllers.
  3. Botnets: Because Struts is often used in enterprise enterprise-facing hardware (like Cisco or Juniper management interfaces), this vulnerability was heavily used to recruit high-bandwidth servers into mining botnets.

The fact that this can be triggered by a single curl command against the login page (or any page using the multipart parser) makes it a "spray and pray" favorite for script kiddies and nation-states alike.

The Fix: Closing the Window

If you are running Struts 2.3.x < 2.3.32 or 2.5.x < 2.5.10.1, you are vulnerable. Stop reading and patch.

Remediation Steps:

  1. Upgrade: Move to Struts 2.5.33 or later immediately. The architecture has changed significantly to prevent OGNL injection.
  2. WAF Rules: If you cannot patch (why?), you must block any HTTP request where the Content-Type header contains %, #, or multipart/form-data followed by OGNL syntax.

> [!WARNING] > Blocking multipart/form-data entirely will break file uploads. You must specifically look for OGNL markers like %{ or ${ inside the header value.

  1. Switch Parsers: You can configure Struts to use the cos or pell multipart parsers instead of jakarta in your struts.xml, though this may have functional side effects.

Official Patches

Apache StrutsOfficial Advisory S2-045

Fix Analysis (1)

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
94.27%
Top 1% most exploited
5,000
Estimated exposed hosts via Shodan

Affected Systems

Apache Struts 2.3.5 - 2.3.31Apache Struts 2.5.0 - 2.5.10Oracle WebLogic ServerCisco Identity Services EngineVMware Horizon View

Affected Versions Detail

Product
Affected Versions
Fixed Version
Apache Struts 2
Apache
2.3.5 - 2.3.312.3.32
Apache Struts 2
Apache
2.5.0 - 2.5.102.5.10.1
AttributeDetail
CWE IDCWE-917
Attack VectorNetwork (HTTP Header)
CVSS v3.19.8 (Critical)
Exploit StatusActive / Weaponized
KEV ListedYes
EPSS Score0.9427 (Very High)

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1059.001Command and Scripting Interpreter: PowerShell
Execution
T1203Exploitation for Client Execution
Execution
CWE-917
Expression Language Injection

Improper Neutralization of Special Elements used in an Expression Language Statement ('Expression Language Injection')

Known Exploits & Detection

ExploitDBApache Struts 2.3.5 < 2.3.31 / 2.5 < 2.5.10 - 'Jakarta Multipart Parser' Remote Code Execution (Python)
MetasploitApache Struts 2 Jakarta Multipart Parser OGNL Injection
NucleiDetection Template Available

Vulnerability Timeline

Vulnerability fixed in code
2017-03-06
Public Disclosure (S2-045)
2017-03-07
Active Exploitation Detected by Talos
2017-03-08
Equifax Breach Begins (Approximate)
2017-05-12

References & Sources

  • [1]S2-045 Security Bulletin
  • [2]Talos Intelligence: Active Exploitation of Apache Struts
Related Vulnerabilities
CVE-2017-5638CVE-2018-11776

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.