CVE-2026-34151: XWiki Platform Old Core Path Traversal via /skin/ Endpoint on Jetty 12
A double-percent-encoded path in XWiki's /skin/ action lets any unauthenticated user read arbitrary files from the server filesystem, including /etc/passwd and WEB-INF config files, when running on Je
The problem
The `/bin/skin/` action in xwiki-platform-oldcore passes the request path to a resource loader without fully normalizing double-encoded traversal sequences before validating it. On Jetty 12+, the servlet container performs a second round of URI decoding, turning `%252f` first into `%2f` and then into `/`.
This lets an unauthenticated attacker escape the webapp root entirely. Reading `/etc/passwd` or sensitive files like `WEB-INF/xwiki.cfg` and `WEB-INF/hibernate.cfg.xml` requires no login and no special privileges. The default Docker image layout (webapp five levels below `/`) makes the full filesystem traversal reproducible out of the box.
Proof of concept
A working proof-of-concept for CVE-2026-34151 in org.xwiki.platform:xwiki-platform-oldcore, with the exact payload below.
# Read /etc/passwd (Docker image layout, webapp 5 levels below /)
GET /xwiki/bin/skin/..%252f/..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc/passwd HTTP/1.1
Host: target.example.com
# Read WEB-INF config without leaving the webapp
GET /xwiki/bin/skin/..%252f/..%252fWEB-INF/xwiki.cfg HTTP/1.1
Host: target.example.comJetty 12 introduced a second URI normalization pass. The sequence `%252f` is first decoded to the literal string `%2f` by the application, then Jetty decodes `%2f` to `/`, producing an unintended directory separator that bypasses XWiki's existing traversal check.
The root cause is CWE-23: the skin action resolves the resource path against the filesystem before stripping or rejecting double-encoded dot-segments. The fix in xwiki-commons PR #1675 (XCOMMONS-3594) adds post-decode normalization and rejection of traversal patterns in the resource path handler, so the path is sanitized after all decoding rounds have occurred, not before.
The fix
Upgrade to XWiki 17.10.5 or 18.2.0. The fix is in xwiki-commons PR #1675 (XCOMMONS-3594). If you cannot upgrade immediately, switch to Tomcat or Jetty < 12 as a temporary workaround, since those containers are not affected by the double-decoding behavior.
Reported by Lê Ngọc Khoa.
Related research
- high · 7.7CVE-2026-54641CVE-2026-54641: OpenRemote Manager Cross-Realm User Information Disclosure
- high · 7.6CVE-2026-54640CVE-2026-54640: OpenRemote KNXProtocol XXE Arbitrary File Read
- highCVE-2026-53712CVE-2026-53712: scram-client SCRAM Channel-Binding Silent Authentication Downgrade
- high · 7.5CVE-2026-46487CVE-2026-46487: GeoNetwork Elasticsearch Search ACL Bypass via Missing Query Field