How this bug class keeps getting shipped
Path traversal in a file-upload endpoint is one of the oldest failure modes on the web. It has a Common Weakness Enumeration entry older than most engineers reading this post, a canned OWASP write-up, static-analysis rules that fire on the first ../, and a generation of penetration-test reports that treat it as table stakes. Yet on 2026-09-24, CISA added CVE-2026-5430 to the Known Exploited Vulnerabilities catalog: a path traversal in WSO2 API Manager, API Control Plane, Traffic Manager and Universal Gateway that permits unrestricted file upload and leads to remote code execution. Same bug, same shape, shipping in 2026.
This is a defensive walkthrough of that class, using CVE-2026-5430 as the lead exhibit and CVE-2026-93616 (a Check Point path-traversal-to-script-execution across Security Management Server, Multi-Domain Security Management, Log Server, Multi-Domain Log Server and SmartEvent; KEV 2026-09-22) as the corroborating case. Two products, two vendors, one bug class, both actively exploited. By the end, a reader knows exactly what the flaw is, what an attacker needs to weaponize it, and how to determine whether their estate is exposed.
The anatomy: upload plus resolve plus execute
The archetype has three moving parts; all three must align before it becomes a remote code execution primitive:
- An HTTP endpoint that accepts a file and takes the filename (or a path component) from attacker-controlled input, often a
Content-Dispositionheader, afilenameform field, or a JSON body. - A server-side handler that joins that untrusted name onto a "safe" base directory using naive string concatenation or a language primitive that does not enforce containment.
- A downstream consumer that will execute, deserialize, render, or otherwise honor files under some path the attacker can now reach. On a Java stack that consumer is usually a servlet container's
webapps/tree, a JSP renderer, a scheduled-task directory, or a class-loader search path.
A minimal reproduction of the vulnerable pattern:
// UNSAFE: filename is attacker-controlled, base is trusted,
// but File(base, name) does not enforce containment.
String name = request.getHeader("X-Filename"); // e.g. "../../webapps/ROOT/x.jsp"
File dest = new File(uploadDir, name);
try (InputStream in = request.getInputStream();
OutputStream out = new FileOutputStream(dest)) {
in.transferTo(out);
}
Nothing in that snippet asks the operating system whether the resolved path still lives under uploadDir. The fix is canonicalization plus a prefix comparison against the real path of the base directory, performed after symlink resolution:
Path base = uploadDir.toPath().toRealPath();
Path dest = base.resolve(name).normalize().toRealPath();
if (!dest.startsWith(base)) {
throw new SecurityException("path escapes upload dir");
}
toRealPath() is the step that gets skipped. normalize() alone collapses ../ sequences textually but does not follow a symlink that points outside the tree, and accepts an absolute path if the platform's resolve() semantics allow it.
What CVE-2026-5430 tells us
CISA's KEV entry for CVE-2026-5430 is deliberately terse: a path traversal that "could allow for unrestricted file upload and lead to remote code execution" in WSO2 API Control Plane, API Manager, Traffic Manager and Universal Gateway. Four products, one shared code path. That fan-out is the tell. When the same CVE covers four SKUs from one vendor, the vulnerable helper almost always lives in a shared platform module that every product embeds. Patching one product does not immunize the others; each receives a separate advisory on the vendor's own timeline, and defenders must track each SKU independently.
For the class, the reachability question is: what does the API gateway do with an uploaded artifact once it lands? In a servlet-container world, dropping a .jsp under the deployed web application directory yields code execution on the next request; dropping a JAR into a hot-deploy directory yields it on the next class-load; dropping a script into a scheduled-task directory yields it on the next tick. The exact primitive varies, but the precondition is write access anywhere on disk as the service account, which the traversal grants.
What CVE-2026-93616 confirms
The Check Point entry the same week describes exactly the second half of that chain: "path traversal vulnerability that allows an unauthenticated attacker to upload and execute arbitrary scripts" across Security Management Server, Multi-Domain Security Management Server, Log Server, Multi-Domain Log Server and SmartEvent. One CVE, five product surfaces, unauthenticated. The KEV language is careful: it does not assert that the two bugs share code, and there is no basis for that claim. What they share is a shape, and the shape is what drives recurrence.
What an attacker actually needs
For both CVEs, network reachability to the management or gateway plane is the only prerequisite. Neither entry mentions authentication. If the affected surface is exposed to the internet, or to any network segment an intruder can already reach, the attacker needs only an HTTP client and the right filename. This is why traversal-to-RCE on management planes ranks so high in intrusion telemetry: it is a one-request, credential-free primitive.
How to tell whether you are exposed
Three questions, in order:
- Do you run any of the named SKUs, at any version, on any segment? "Any segment" includes the management VLAN, out-of-band networks, and lab environments that route to production. Inventory by installed package, not by what the CMDB claims.
- Is the affected surface reachable from any principal you do not fully trust? Treat your own users as untrusted for management planes; that is the whole point of the KEV framing.
- Have you applied the vendor's fixed build? If not, is the surface behind a compensating control that terminates HTTP and enforces path constraints on upload endpoints before they reach the appliance?
Detection is unglamorous but effective. Log every upload endpoint's filename and Content-Disposition on the reverse proxy, not just the application, and alert on any value containing .., a leading /, a drive letter, a NUL byte, or a URL-encoded variant of any of those. In parallel, run a file-integrity monitor over the servlet container's deployed-application tree and any hot-deploy directory. A new .jsp, .war, .jar, .sh or .py that no change ticket accounts for is the ground-truth signal that the class has fired.
Why the class does not die
Three structural reasons. First, filename handling looks trivial, so engineers write it by hand rather than delegate to a hardened library, and hand-written path joins skip the canonicalize-and-compare step nine times out of ten. Second, upload endpoints proliferate across admin consoles, plugin loaders, log ingestion, backup restore, and certificate import; each is a separate opportunity to get it wrong. Third, a single mistake yields the entire host, because the service account almost always has write access to a directory the platform will later execute from.
CISA's KEV catalog, now carried into federal remediation directive BOD 26-04, is not a survey; it is a live list of bugs adversaries are using right now. When a path traversal lands there, the correct posture is not "we will get to it in the next patch window." Patch the SKU on the vendor's fixed build, restrict the management plane to a bastioned network, and instrument the upload surface so the next instance of this class becomes a detection, not an incident.
Verifiable security.