high · 8.8CVE-2026-49473Jun 30, 2026

CVE-2026-49473: @cedar-policy/authorization-for-expressjs Authorization Bypass via Query String

Shubham Kandhare
Security Engagement Manager, SecureLayer7

A query string appended to a request URL tricks the Cedar middleware into evaluating a less restrictive authorization policy while Express routes the request to a more privileged endpoint, letting an

Package@cedar-policy/authorization-for-expressjs
Ecosystemnpm
Affected<= 0.2.0
Fixed in0.3.0

The problem

The middleware matched incoming requests to Cedar action mappings using req.originalUrl, which includes the query string. Express routes requests using only the path component.

When an app defines overlapping path prefixes with different permission levels, for example GET /users (admin only) and GET /users/{id} (any authenticated user), an attacker can append a query string like ?x=1 to the restricted path. Cedar sees /users/?x=1 and matches it to the /users/{id} pattern, evaluating the weaker policy, while Express still routes the request to the /users list handler.

Proof of concept

A working proof-of-concept for CVE-2026-49473 in @cedar-policy/authorization-for-expressjs, with the exact payload below.

http
GET /users/?x=1 HTTP/1.1
Host: target.example.com
Authorization: Bearer <authenticated-user-token>

The root cause is an interpretation conflict (CWE-115) between two consumers of the same request URL. Before the patch, the middleware called req.originalUrl to resolve which Cedar action to evaluate. req.originalUrl preserves the raw query string, so /users/?x=1 matched the /users/{id} route pattern instead of /users, causing Cedar to authorize against the wrong, less restrictive action.

The v0.3.0 patch switches the action-matching logic to use req.path, which Express normalizes to the path component only, stripping any query string. This eliminates the divergence between what Cedar authorizes and what Express executes.

The fix

Upgrade to @cedar-policy/authorization-for-expressjs version 0.3.0 or later. As a workaround on older versions, sanitize and strip query strings from request paths before they reach the authorization middleware, and avoid defining overlapping path-prefix routes with different permission levels.

Reported by AWS Security.

References: [1][2][3]

Related research