CVE-2026-39852: Quarkus Authorization Bypass via Matrix Parameters
How a matrix-parameter path-normalization mismatch lets an unauthenticated request slip past Quarkus authorization policies

On May 4, 2026, the Quarkus team published GHSA-rc95-pcm8-65v9 for CVE-2026-39852, a High-severity authorization bypass reported by GitHub Security Lab. GitHub scores it 8.8 on CVSS v4 (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N); NVD scores it 8.2 on CVSS v3.1 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N). The flaw (CWE-551) is a path-normalization mismatch in io.quarkus:quarkus-vertx-http: the security layer authorizes the raw request path, which still carries semicolon-delimited matrix parameters, while RESTEasy Reactive strips those parameters before it routes the request. So a request to //api/admin;anything is checked against a policy that protects //api/admin, misses, and is then dispatched to the protected handler anyway. It affects Quarkus below 3.20.6.1, from 3.21.0 up to 3.27.3.1, from 3.30.0 up to 3.33.1.1, and from 3.34.0 up to 3.35.1.1. Maintained lines have upstream fixes. EOL lines such as 2.16.x have no OSS fix in their own version line.
Affected and unsupported? See NES for Quarkus.
What is CVE-2026-39852?
CVE-2026-39852 is an authorization bypass in the quarkus-vertx-http extension, which handles HTTP for the vast majority of Quarkus applications. GitHub's advisory classifies it under CWE-551, Incorrect Behavior Order: Authorization Before Parsing and Canonicalization of a URL, and cross-references CWE-287 (Improper Authentication) and CWE-863 (Incorrect Authorization). Red Hat's analysis uses the same CWE-551 root cause.
The short version: Quarkus makes its authorization decision on a version of the URL that the router later throws away. An attacker adds a matrix parameter, a segment introduced with a semicolon such as /;x=1 or just /;anything, to a protected path. The security layer sees //api/admin;anything, decides that string does not match the rule guarding //api/admin, and lets the request through. RESTEasy Reactive then strips the matrix parameter, matches //api/admin, and invokes the protected endpoint. The check and the dispatch look at two different paths, and the gap between them is the vulnerability.
Matrix parameters are a legitimate, if rarely used, part of the URI syntax (RFC 3986 path segments can carry semicolon-delimited name-value pairs). Most applications never use them. That is exactly why they make a clean bypass primitive: the routing layer knows to discard them, and the security layer does not.
Root cause: authorization runs before the path is canonicalized
CWE-551 names the defect precisely. Authorization happens before the URL is parsed and canonicalized, so the two layers never agree on what path is actually being requested.
Quarkus HTTP path-based authorization is configured with permission policies. A typical rule pairs a path with a policy, for example quarkus.http.auth.permission.admin.paths=/api/admin alongside quarkus.http.auth.permission.admin.policy=admin-role, which restricts //api/admin to an admin role. When a request arrives, the security layer evaluates that rule against the raw request path. Matrix parameters survive into the raw path, so //api/admin;anything is treated as a distinct string that does not match //api/admin. The policy that should fire never does.
RESTEasy Reactive, the routing layer, does the opposite. It normalizes the path and drops matrix parameters before matching an endpoint, because that is correct behavior for dispatch: //api/admin;anything and //api/admin should route to the same resource method. The request that the security layer waved through as "not the admin path" is handed to the admin handler.
The consequence generalizes. Any security decision that keys off the raw request path, before that path is canonicalized, is in the same exposure class as the confirmed HTTP permission-policy bypass. If a control decides access by comparing the incoming path string to an expected value, the matrix-parameter trick can move the two comparisons out of sync. The advisory and Red Hat's writeup confirm the impact on Quarkus HTTP path-based authorization policies specifically. Treat any other path-driven guard in your application as suspect until you have confirmed it normalizes the path first.
Severity and exploit conditions
PR:N is the number that matters. No credentials are required. The advisory notes that lower-privileged authenticated users can also use the trick to reach endpoints above their privilege level, but the base case is a fully unauthenticated attacker.
The scores diverge by version and by vendor, and all of them land in High. NVD scores CVSS v3.1 at 8.2 with a confidentiality-weighted vector (C:H/I:L/A:N). Red Hat also scores v3.1 at 8.2 but weights the impact toward availability (C:N/I:L/A:H). GitHub scores CVSS v4 at 8.8. We recomputed each vector independently and they check out. The version difference (v3.1 versus v4) explains most of the gap; the takeaway is unchanged.
Exploitation status
There is no separate weaponized exploit to publish, because the technique is a single crafted URL and the advisory documents it directly: append a semicolon segment to a path that a permission policy is supposed to protect. Reproduction against your own application is a matter of adding /;x to a protected route and watching whether the handler still runs.
As of this writing, CVE-2026-39852 is not listed in the CISA Known Exploited Vulnerabilities catalog, and we have found no reports of active exploitation in the wild. That is not a reason to defer patching. The barrier to exploitation is close to zero, and the vulnerability is trivially discoverable by scanning for path-based auth rules.
What an attacker can do
The concrete impact is unauthorized access to any endpoint guarded solely by a Quarkus HTTP path-based permission policy:
- Invoke an admin or management endpoint protected by a rule like quarkus.http.auth.permission.admin.paths=/api/admin by requesting //api/admin;x with no credentials.
- Reach role-restricted business endpoints when the role requirement is enforced by a path policy rather than a per-method annotation that runs after routing.
- Chain the bypass into whatever the exposed endpoint does. If the protected handler reads sensitive records, triggers a privileged action, or mutates state, the attacker inherits that capability without ever authenticating.
Because the routing layer dispatches to the real handler, the bypassed request is not a dead end. It executes with the authorization check skipped, not merely accepted at the edge.
Who is affected?
The affected ranges are non-contiguous, which is the detail most teams need to check carefully. These are the ranges from the advisory, with the version that closes each one:
The mismatch to watch: the fix for everything below 3.20.6.1 is 3.20.6.1 itself, which sits in the 3.20 LTS line. For a team on a maintained 3.20 build, that is a routine patch upgrade. For a team on any line below 3.20, it is not a patch at all. It is a major version migration, and no in-line fix exists for their branch.
There is a wrinkle in the 3.20 line worth calling out. Quarkus 3.20 reached its community maintenance end of life on March 28, 2026 (per endoflife.date). The patched release 3.20.6.1 shipped on May 4, 2026, more than a month after that window closed. In other words, the only reason a 3.20 user got an in-line fix at all is that the upstream team chose to publish one past their own EOL date. That is a favor, not a guarantee. A security posture that depends on the upstream team making an exception is not a posture. The next CVE in a line that is already past EOL may not get the same treatment, and lines like 2.16.x did not get it this time.
Mitigation guidance
Defense-in-depth is a stopgap, not a fix. Stripping semicolons at the edge closes the specific matrix-parameter primitive, but it does not repair the underlying order-of-operations defect, and it depends on every ingress path being covered. Patch the framework, then keep the proxy rule as a second layer.
Related CVEs
CVE-2026-39852 sits in a recognizable class of authorization bypasses that come from two layers disagreeing about what a URL means. Related entries in the HeroDevs vulnerability directory:
- CVE-2024-2700, a separate Quarkus vulnerability tracked in the directory.
- CVE-2024-38821, a Spring Security authorization bypass for static resources, the same category of path-based authorization gap in a different framework.
- CVE-2024-22243, a Spring Framework URL-parsing inconsistency, another case where non-obvious URL handling undermines a security assumption.
Taking action
If you run Quarkus, the first step is to find out which line you are on and whether it is below the fix for that line. Maintained lines get a straightforward upgrade to 3.20.6.1, 3.27.3.1, 3.33.1.1, or 3.35.1.1. That is the right move when it is available to you.
The harder case is an EOL line. Anything below 3.20, including 2.16.x and the older 3.x LTS branches, has no in-line OSS fix for this CVE. Your OSS options are a major migration or nothing, and 3.20 itself is now past its own community EOL. If migrating on a security team's timeline is not realistic, NES for Quarkus gives you a patched, drop-in build of the exact version you run today, so you close CVE-2026-39852 without betting your posture on whether upstream decides to make another exception.
Sources: the upstream advisory GHSA-rc95-pcm8-65v9 and the NVD entry for CVE-2026-39852.
Resources
View All Articles


