Every CVE Search/ Get API key

CVE-2026-8384

Eclipse Jetty: Path parameter traversal

5.3 MediumFix available

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

0.33%Up 0.1 points since Jul 14, 2026
90%50%10%1%

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 MediumCVSS: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 MediumCVSS: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 MediumCVSS: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 MediumCVSS: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 MediumCVSS: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 MediumCVSS: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 MediumCVSS: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 MediumCVSS: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

Affected packages
PackageAffectedFixed
org.eclipse.jetty:jetty-util
Maven
12.0.0 to 12.0.34
12.0.35
org.eclipse.jetty:jetty-util
Maven
12.1.0 to 12.1.8
12.1.9
jetty12
Debian: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 less
12.0.33-112.0.39-112.0.40-112.0.40-2
None known
jetty12
Debian: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
jetty9
Debian: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 less
9.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
jetty9
Debian: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
jetty9
Debian: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-util
Maven
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 less
12.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-util
Maven
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
jetty9
Ubuntu:16.04:LTS
All versions, plus listed versions
9.2.14-1
None known
Show 8 moreShow less
Affected packages
PackageAffectedFixed
jetty9
Ubuntu: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
jetty9
Ubuntu:20.04:LTS
All versions, plus listed versions
9.4.18-2build29.4.26-1
None known
jetty9
Ubuntu: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
jetty9
Ubuntu:24.04:LTS
All versions, plus listed versions
9.4.51-29.4.53-1
None known
jetty12
Ubuntu:26.10
All versions, plus listed versions
12.0.32-1
None known
jetty9
Ubuntu:26.10
All versions, plus listed versions
9.4.58-19.4.58-2
None known
jetty12
Ubuntu:26.04:LTS
All versions, plus listed versions
12.0.17-3.112.0.32-1
None known
jetty9
Ubuntu:26.04:LTS
All versions, plus listed versions
9.4.57-19.4.57-1.19.4.58-1
None known

History

History
RecordedChangedSources
affected, factsOSV
first indexedCVE 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

Show 9 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open