Lede
In August 2018, security researcher Man Yue Mo of the Semmle Security Research Team (now part of GitHub Security Lab) disclosed CVE-2018-11776, a critical remote code execution vulnerability in Apache Struts2. The flaw lives in how the Struts core evaluates the "namespace" value used to route incoming requests to actions. Under specific — but far from rare — configuration conditions, an attacker can craft a malicious URL that gets evaluated as an OGNL (Object-Graph Navigation Language) expression, resulting in arbitrary code execution on the server with no authentication required.
Struts2 has a well-earned reputation as a repeat offender in the OGNL-injection hall of fame: CVE-2017-5638, the vulnerability behind the 2017 Equifax breach, is the most infamous example. CVE-2018-11776 follows the same family of bugs — untrusted input reaching OGNL evaluation — but the trigger surface is different, which is precisely why it slipped past patches for earlier Struts CVEs and required its own fix.
Affected versions and components
CVE-2018-11776 affects Apache Struts2 in the following version ranges:
- Struts 2.3.x through 2.3.34
- Struts 2.5.x through 2.5.16
The fix landed in Struts 2.3.35 and 2.5.17, released alongside Apache's security advisory (tracked internally as S2-057).
The vulnerability is not universally exploitable across every Struts deployment — it depends on how the application's struts.xml configuration handles namespaces. Two conditions materially affect exploitability:
- Wildcard or missing namespace configuration. The bug triggers when a
<result>element does not have its namespace explicitly set, and an enclosing<action>(or the package itself) uses no namespace or a wildcard namespace. A parallel condition exists for the<s:url>JSP tag when it is used without avalueoractionattribute inside a package that has no or wildcard namespace configured. alwaysSelectFullNamespacesetting. Exploitability is significantly more likely when the Struts configuration hasalwaysSelectFullNamespaceset totrue. This setting is not always the developer's explicit choice — it is set totrueby default when the popular Struts Convention plugin is used, which broadened the real-world blast radius considerably since many Struts applications rely on Convention for annotation-based action mapping.
In short: any application built on affected Struts versions using wildcard namespace mappings, or using the Convention plugin, should be treated as exploitable until proven otherwise.
CVSS, EPSS, and KEV context
NVD scored CVE-2018-11776 as High severity, with a CVSS v3 base score in the 8.1 range (network-exploitable, no privileges or user interaction required, high impact to confidentiality, integrity, and availability, but with high attack complexity due to the configuration prerequisites described above). The "high attack complexity" component reflects the fact that exploitation depends on the namespace/alwaysSelectFullNamespace conditions rather than affecting every Struts2 install unconditionally — but for the substantial population of apps that do meet those conditions, the practical impact is a full, unauthenticated remote shell.
At the time of writing, we could not confirm whether CVE-2018-11776 currently appears on CISA's Known Exploited Vulnerabilities (KEV) catalog; readers relying on KEV status for prioritization should check CISA's catalog directly rather than assume based on this post. What is well documented, however, is that this CVE saw rapid, widespread exploitation attempts in the wild within days of disclosure — security vendors and researchers observed internet-wide scanning and exploitation activity almost immediately after the advisory and proof-of-concept exploit code became public, echoing the exploitation speed seen with prior Struts OGNL bugs. Given Struts2's history (2017-5638 being weaponized within 24-48 hours of disclosure and used against Equifax before many organizations had patched), any newly disclosed Struts RCE should be assumed to be under active or imminent mass exploitation the moment technical details circulate.
Timeline
- Disclosure/advisory: Man Yue Mo of Semmle reported the vulnerability responsibly to the Apache Struts project. Apache published security advisory S2-057 along with the CVE and patched releases.
- Patch availability: Struts 2.3.35 and 2.5.17 were released containing the fix, requiring applications to either upgrade or apply the documented configuration mitigations.
- Public technical writeup: Semmle published a detailed technical breakdown of the root cause (the namespace/OGNL evaluation path) shortly after the coordinated disclosure, which — as is typical with high-profile Struts bugs — was quickly followed by public proof-of-concept exploits and observed scanning/exploitation activity across the internet.
Because Struts2 is embedded deep inside countless enterprise Java applications (often as a transitive dependency several layers removed from the team that would need to patch it), the practical remediation timeline for many organizations lagged well behind the availability of the fix — a pattern that has repeated across nearly every major Struts CVE and is a central reason this vulnerability class keeps producing breaches years after patches exist.
Remediation steps
- Upgrade Struts2. The definitive fix is upgrading to Struts 2.3.35 or 2.5.17 (or later, if a more recent line is in use). Do not treat configuration mitigations as a permanent substitute for patching.
- Audit
struts.xmlfor wildcard/missing namespaces. If you cannot upgrade immediately, review every<package>and<action>definition. Ensure namespaces are explicitly and consistently set rather than relying on wildcards or omission, and check every<result>element for an explicit namespace where applicable. - Check for the Convention plugin and
alwaysSelectFullNamespace. If your application usesstruts2-convention-plugin, assumealwaysSelectFullNamespaceistrueunless you have explicitly overridden it. Explicitly set it tofalsewhere your routing design allows, as an interim mitigation. - Audit
<s:url>tag usage. Search JSPs for<s:url>tags that omit bothvalueandactionattributes, and add explicit values where the enclosing package namespace is missing or wildcarded. - Inventory transitive dependencies. Struts2 frequently arrives bundled inside vendor products, internal frameworks, or third-party WARs rather than as a direct, visible dependency. A full SBOM-driven inventory is the only reliable way to know whether Struts2 — and this specific vulnerable version range — is present anywhere in your estate, including in software you didn't build in-house.
- Monitor and virtually patch where upgrades are slow. For systems that cannot be patched quickly (e.g., vendor-controlled appliances), deploy WAF/IPS signatures targeting OGNL injection patterns in URL paths as a stopgap, and increase logging on affected endpoints to detect exploitation attempts.
- Assume compromise if exposed and unpatched for an extended window. Given the documented speed of internet-wide scanning after Struts CVE disclosures, any internet-facing, unpatched, vulnerable instance should be treated as a potential incident-response case, not just a patching task.
How Safeguard Helps
CVE-2018-11776 is a textbook example of why supply chain visibility matters as much as patch velocity. The vulnerability rarely lives in code your developers wrote directly — it lives in a framework version pulled in by a build file, bundled inside a vendor artifact, or inherited from a base image that hasn't been rebuilt in years. Finding it requires knowing, with certainty, everywhere Struts2 exists across your software supply chain, not just in the repositories your team remembers.
Safeguard is built for exactly this problem. Our platform continuously generates and maintains accurate software bills of materials (SBOMs) across your build pipelines, containers, and deployed artifacts, so a vulnerability like CVE-2018-11776 surfaces as a concrete, actionable hit — down to the specific artifact, version, and location — rather than a manual grep exercise across dozens of repositories. Because Struts2 is so often a transitive or vendor-embedded dependency, Safeguard's dependency graph analysis is designed to catch it even when it's several layers removed from your top-level manifests.
Beyond detection, Safeguard correlates identified components against CVE and exploitation-activity data so your team can prioritize based on real-world risk — distinguishing a Struts2 instance sitting behind an internal network from one exposed on the public internet with a wildcard namespace configuration ripe for exploitation. That context is what turns a generic "you have a vulnerable library" alert into an actionable, risk-ranked remediation item your AppSec and DevOps teams can act on before attackers do.
If your organization has any Java applications built on Struts2 — whether developed in-house, inherited through acquisition, or embedded in third-party software — treating CVE-2018-11776 as resolved requires proof, not assumption. Safeguard gives you that proof, continuously, as your software supply chain evolves.