CVE-2026-8384
Eclipse Jetty: Path parameter traversal
In Eclipse Jetty, an HTTP URI of this form:
/public;/../admin/secret.txt
results in an unresolved path of:
/public/../admin/secret.txt
instead of the expected:
/admin/secret.txt
Jetty itself is not affected, as it will not serve the secret.txt file because it will not pass the alias checker (only resolved resources are served).
However, web applications that rely on resolved paths being provided by Jetty may be confused when receiving an unresolved path.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
5.3
In Eclipse Jetty, an HTTP URI of this form:
/public;/../admin/secret.txt
results in an unresolved path of:
/public/../admin/secret.txt
instead of the expected:
/admin/secret.txt
Jetty itself is not affected, as it will not serve the secret.txt file because it will not pass the alias checker (only resolved resources are served).
However, web applications that rely on resolved paths being provided by Jetty may be confused when receiving an unresolved path.
- Record
CVE-2026-8384- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-647
- Updated
- 2026-11-02
EUVDEUVD-2026-43647
5.3
In Eclipse Jetty, an HTTP URI of this form:
/public;/../admin/secret.txt
results in an unresolved path of:
/public/../admin/secret.txt
instead of the expected:
/admin/secret.txt
Jetty itself is not affected, as it will not serve the secret.txt file because it will not pass the alias checker (only resolved resources are served).
However, web applications that rely on resolved paths being provided by Jetty may be confused when receiving an unresolved path.
- Record
EUVD-2026-43647- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-w7x5-g22v-xqhr
5.3
Eclipse Jetty: Path parameter traversal
Description (as reported)
Summary
In Jetty 12.1.8, org.eclipse.jetty.util.URIUtil.canonicalPath() may leave dot-dot path segments unnormalized when a semicolon path parameter marker is followed by a slash and a dot segment.
A minimal example is:
/public;/../admin/secret
In my local reproduction, URIUtil.canonicalPath() returns:
/public/../admin/secret
instead of the expected normalized path:
/admin/secret
When Jetty's SecurityHandler.PathMapped is used to protect a path prefix such as /admin/*, the non-normalized canonical path may not match the protected prefix. As a result, an unauthenticated request may bypass the configured path-based security constraint.
Tested Version
Jetty: 12.1.8 JDK: 17.0.18 Maven: 3.9.14
Maven artifacts used:
org.eclipse.jetty:jetty-server:12.1.8 org.eclipse.jetty:jetty-security:12.1.8 org.eclipse.jetty:jetty-session:12.1.8
Only confirmed Jetty 12.1.8 so far.
Minimal Reproduction
Starts a minimal Jetty server with the following security setup:
SecurityHandler.PathMapped security = new SecurityHandler.PathMapped();
security.put("/admin/*", Constraint.from("admin"));
security.put("/*", Constraint.ALLOWED);
security.setAuthenticator(new BasicAuthenticator());
The test then sends requests with no Authorization header.
Observed result:
GET /admin/secret -> 401
GET /public;x/../admin/secret -> 200
The handler receives paths such as:
/public/../admin/secret
This suggests that the /admin/* security constraint is bypassed because PathMapped matching is performed against the non-normalized canonical path.
Suspected Root Cause
The suspected root cause is in URIUtil.canonicalPath().
The relevant logic is approximately:
for (int i = 0; i < end; i++)
{
char c = encodedPath.charAt(i);
switch (c)
{
case ';':
if (builder == null)
{
builder = new Utf8StringBuilder(encodedPath.length());
builder.append(encodedPath, 0, i);
}
while (++i < end)
{
if (encodedPath.charAt(i) == '/')
{
builder.append('/');
break;
}
}
break;
case '.':
if (slash)
normal = false;
if (builder != null)
builder.append(c);
break;
}
slash = c == '/';
}
String canonical = (builder != null)
? (onBadUtf8 == null ? builder.toCompleteString() : builder.takeCompleteString(onBadUtf8))
: encodedPath;
return normal ? canonical : normalizePath(canonical);
For the input:
/public;/../admin/secret
when the outer loop reaches the semicolon:
i = 7
c = ';'
slash = false
normal = true
Inside case ';', the while (++i < end) loop advances i to the next character, which is already '/' for the empty path parameter form ";/".
The code then appends '/' to the canonical builder:
builder.append('/');
At this point, the canonical builder ends with '/':
/public/
However, the local variable c is still the old value ';', because c was read before entering the switch and is not updated when the inner loop advances i.
After leaving the switch, the loop updates the slash state using:
slash = c == '/';
Since c is still ';', slash becomes false.
On the next iteration, the scanner reaches '.', which is the first dot in the following "../" segment. Because slash is incorrectly false, this code does not run:
if (slash)
normal = false;
Therefore normal remains true, and canonicalPath() returns the canonical string directly instead of calling normalizePath(canonical).
The result is: …
- Record
GHSA-w7x5-g22v-xqhr- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-647
- Updated
- 2026-11-02
NVD
5.3
In Eclipse Jetty, an HTTP URI of this form:
/public;/../admin/secret.txt
results in an unresolved path of:
/public/../admin/secret.txt
instead of the expected:
/admin/secret.txt
Jetty itself is not affected, as it will not serve the secret.txt file because it will not pass the alias checker (only resolved resources are served).
However, web applications that rely on resolved paths being provided by Jetty may be confused when receiving an unresolved path.
- Record
CVE-2026-8384- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-647
- Updated
- 2026-11-02
OSV
5.3
In Eclipse Jetty, an HTTP URI of this form:
/public;/../admin/secret.txt
results in an unresolved path of:
/public/../admin/secret.txt
instead of the expected:
/admin/secret.txt
Jetty itself is not affected, as it will not serve the secret.txt file because it will not pass the alias checker (only resolved resources are served).
However, web applications that rely on resolved paths being provided by Jetty may be confused when receiving an unresolved path.
- Record
CVE-2026-8384- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-647
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-8384
5.3
In Eclipse Jetty, an HTTP URI of this form: /public;/../admin/secret.txt results in an unresolved path of: /public/../admin/secret.txt instead of the expected: /admin/secret.txt Jetty itself is not affected, as it will not serve the secret.txt file because it will not pass the alias checker (only resolved resources are served). However, web applications that rely on resolved paths being provided by Jetty may be confused when receiving an unresolved path.
- Record
DEBIAN-CVE-2026-8384- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N - Updated
- 2026-11-04
OSVGHSA-w7x5-g22v-xqhr
5.3
Eclipse Jetty: Path parameter traversal
Description (as reported)
Summary
In Jetty 12.1.8, org.eclipse.jetty.util.URIUtil.canonicalPath() may leave dot-dot path segments unnormalized when a semicolon path parameter marker is followed by a slash and a dot segment.
A minimal example is:
/public;/../admin/secret
In my local reproduction, URIUtil.canonicalPath() returns:
/public/../admin/secret
instead of the expected normalized path:
/admin/secret
When Jetty's SecurityHandler.PathMapped is used to protect a path prefix such as /admin/*, the non-normalized canonical path may not match the protected prefix. As a result, an unauthenticated request may bypass the configured path-based security constraint.
Tested Version
Jetty: 12.1.8 JDK: 17.0.18 Maven: 3.9.14
Maven artifacts used:
org.eclipse.jetty:jetty-server:12.1.8 org.eclipse.jetty:jetty-security:12.1.8 org.eclipse.jetty:jetty-session:12.1.8
Only confirmed Jetty 12.1.8 so far.
Minimal Reproduction
Starts a minimal Jetty server with the following security setup:
SecurityHandler.PathMapped security = new SecurityHandler.PathMapped();
security.put("/admin/*", Constraint.from("admin"));
security.put("/*", Constraint.ALLOWED);
security.setAuthenticator(new BasicAuthenticator());
The test then sends requests with no Authorization header.
Observed result:
GET /admin/secret -> 401
GET /public;x/../admin/secret -> 200
The handler receives paths such as:
/public/../admin/secret
This suggests that the /admin/* security constraint is bypassed because PathMapped matching is performed against the non-normalized canonical path.
Suspected Root Cause
The suspected root cause is in URIUtil.canonicalPath().
The relevant logic is approximately:
for (int i = 0; i < end; i++)
{
char c = encodedPath.charAt(i);
switch (c)
{
case ';':
if (builder == null)
{
builder = new Utf8StringBuilder(encodedPath.length());
builder.append(encodedPath, 0, i);
}
while (++i < end)
{
if (encodedPath.charAt(i) == '/')
{
builder.append('/');
break;
}
}
break;
case '.':
if (slash)
normal = false;
if (builder != null)
builder.append(c);
break;
}
slash = c == '/';
}
String canonical = (builder != null)
? (onBadUtf8 == null ? builder.toCompleteString() : builder.takeCompleteString(onBadUtf8))
: encodedPath;
return normal ? canonical : normalizePath(canonical);
For the input:
/public;/../admin/secret
when the outer loop reaches the semicolon:
i = 7
c = ';'
slash = false
normal = true
Inside case ';', the while (++i < end) loop advances i to the next character, which is already '/' for the empty path parameter form ";/".
The code then appends '/' to the canonical builder:
builder.append('/');
At this point, the canonical builder ends with '/':
/public/
However, the local variable c is still the old value ';', because c was read before entering the switch and is not updated when the inner loop advances i.
After leaving the switch, the loop updates the slash state using:
slash = c == '/';
Since c is still ';', slash becomes false.
On the next iteration, the scanner reaches '.', which is the first dot in the following "../" segment. Because slash is incorrectly false, this code does not run:
if (slash)
normal = false;
Therefore normal remains true, and canonicalPath() returns the canonical string directly instead of calling normalizePath(canonical).
The result is: …
- Record
GHSA-w7x5-g22v-xqhr- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-647
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-8384
5.3
In Eclipse Jetty, an HTTP URI of this form: /public;/../admin/secret.txt results in an unresolved path of: /public/../admin/secret.txt instead of the expected: /admin/secret.txt Jetty itself is not affected, as it will not serve the secret.txt file because it will not pass the alias checker (only resolved resources are served). However, web applications that rely on resolved paths being provided by Jetty may be confused when receiving an unresolved path.
- Record
UBUNTU-CVE-2026-8384- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
org.eclipse.jetty:jetty-utilMaven |
12.0.0 to 12.0.34 | 12.0.35 |
org.eclipse.jetty:jetty-utilMaven |
12.1.0 to 12.1.8 | 12.1.9 |
jetty12Debian:13 |
All versions, plus listed versions 12.0.17-312.0.17-3.112.0.17-3.1~deb13u112.0.32-112.0.32-2 Show 4 moreShow less12.0.33-112.0.39-112.0.40-112.0.40-2 |
None known |
jetty12Debian:14 |
before 12.0.39-1, plus listed versions 12.0.17-312.0.17-3.112.0.17-3.1~deb13u112.0.32-112.0.32-212.0.33-1 |
12.0.39-1 |
jetty9Debian:12 |
All versions, plus listed versions 9.4.50-49.4.50-4+deb12u19.4.50-4+deb12u29.4.50-4+deb12u39.4.51-1 Show 13 moreShow less9.4.51-29.4.52-19.4.53-19.4.54-19.4.55-19.4.56-19.4.57-0+deb12u19.4.57-19.4.57-1.19.4.57-1.1~deb12u19.4.57-1.1~deb13u19.4.58-19.4.58-2 |
None known |
jetty9Debian:13 |
All versions, plus listed versions 9.4.57-19.4.57-1.19.4.57-1.1~deb12u19.4.57-1.1~deb13u19.4.58-19.4.58-2 |
None known |
jetty9Debian:14 |
All versions, plus listed versions 9.4.57-19.4.57-1.19.4.57-1.1~deb12u19.4.57-1.1~deb13u19.4.58-19.4.58-2 |
None known |
org.eclipse.jetty:jetty-utilMaven |
12.0.0 up to 12.0.35, plus listed versions 12.0.112.0.1012.0.1112.0.1212.0.13 Show 29 moreShow less12.0.1412.0.1512.0.1612.0.1712.0.1812.0.1912.0.212.0.2012.0.2112.0.2212.0.2312.0.2412.0.2512.0.2612.0.2712.0.2812.0.2912.0.312.0.3012.0.3112.0.3212.0.3312.0.3412.0.412.0.512.0.612.0.712.0.812.0.9 |
12.0.35 |
org.eclipse.jetty:jetty-utilMaven |
12.1.0 up to 12.1.9, plus listed versions 12.1.112.1.212.1.312.1.412.1.512.1.612.1.712.1.8 |
12.1.9 |
jetty9Ubuntu:16.04:LTS |
All versions, plus listed versions 9.2.14-1 |
None known |
Show 8 moreShow less
| Package | Affected | Fixed |
|---|---|---|
jetty9Ubuntu:18.04:LTS |
All versions, plus listed versions 9.2.22-29.2.22-39.2.23-19.4.15-1~18.04.1ubuntu1 |
None known |
jetty9Ubuntu:20.04:LTS |
All versions, plus listed versions 9.4.18-2build29.4.26-1 |
None known |
jetty9Ubuntu:22.04:LTS |
All versions, plus listed versions 9.4.39-39.4.44-29.4.44-39.4.44-49.4.45-1 |
None known |
jetty9Ubuntu:24.04:LTS |
All versions, plus listed versions 9.4.51-29.4.53-1 |
None known |
jetty12Ubuntu:26.10 |
All versions, plus listed versions 12.0.32-1 |
None known |
jetty9Ubuntu:26.10 |
All versions, plus listed versions 9.4.58-19.4.58-2 |
None known |
jetty12Ubuntu:26.04:LTS |
All versions, plus listed versions 12.0.17-3.112.0.32-1 |
None known |
jetty9Ubuntu:26.04:LTS |
All versions, plus listed versions 9.4.57-19.4.57-1.19.4.58-1 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-8384 is a medium vulnerability (CVSS 5.3) in Eclipse Jetty, published July 14, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.33%, the 26th percentile. Fixed in org.eclipse.jetty:jetty-util 12.0.35.
References
gitlab.eclipse.org/security/cve-assignment/-/work_items/108
github.com/jetty/jetty.project/security/advisories/GHSA-w7x5-g22v-xqhr
nvd.nist.gov/vuln/detail/CVE-2026-8384
github.com/jetty/jetty.project/pull/14969
github.com/jetty/jetty.project/pull/14973
github.com/jetty/jetty.project/commit/82969c77f6da46e27008b10b3c14840cd31db084
Show 9 moreShow less
github.com/jetty/jetty.project/commit/ade27ce93a37c33278720250d85c48601230ae3f
github.com/jetty/jetty.project/releases/tag/jetty-12.0.35
github.com/jetty/jetty.project/releases/tag/jetty-12.1.9
github.com/advisories/GHSA-w7x5-g22v-xqhr
github.com/CVEProject/cvelistV5/tree/main/cves/2026/8xxx/CVE-2026-8384.json
github.com/jetty/jetty.project
security-tracker.debian.org/tracker/CVE-2026-8384
ubuntu.com/security/CVE-2026-8384
cve.org/CVERecord?id=CVE-2026-8384
Left out here: the rest of 2 source descriptions. The JSON record has them.