# URL normalization differential allowlist bypass

Security check and downstream handler parse or decode the same URL differently

_Area: Web access control and IDOR. Seen in 5 disclosed reports; one confirmed bounty: $6,000; latest 2026-07-29. Updated 2026-10-24._

## How it works
A security decision (allowlist, ACL, auth policy, sandbox rule) is made on one string, but the URL is later parsed, decoded, or normalized by a different component that disagrees about where the authority, path, or parameters end. The check sees a benign value; the consumer sees an attacker-chosen one. The broken assumption is that "the URL the checker validated" and "the URL the handler acts on" are the same. Any character one parser treats as a delimiter and the other does not creates the gap.

## Where it shows up
- Hand-rolled regexes that split authority on `/ ? #` but not `\` [E1](https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2020-03-08-the-unexpected-google-wide-domain-check-bypass.md)
- Two decode steps on the same component (parse decodes userinfo, ACL match decodes again) [E2](https://bugbountylibrary.com/r/h1%3A824203.md)
- Security layer decodes only unreserved chars while static/file handlers fully percent-decode `%2F`, `%5C`, `%3B` [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-qcxp-gm7m-4j5v.md)
- Matrix params (`;`) stripped by the filter but surviving to the handler [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-qcxp-gm7m-4j5v.md)
- Alternate path spellings (`\\.\localhost/`, device/UNC forms) not normalized before a sandbox check [E4](https://bugbountylibrary.com/r/h1%3A150976.md)
- Any place a filter and a downstream handler each call their own normalize/parse

## How to review
Identify every component that parses the URL between the check and the sink. The invariant: the exact string the policy evaluates must be the exact string the handler acts on, after identical normalization. Concretely:
- Does the checker and the consumer use the same parser, or a regex vs. a real parser? [E1](https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2020-03-08-the-unexpected-google-wide-domain-check-bypass.md)
- Is any component decoded more than once? [E2](https://bugbountylibrary.com/r/h1%3A824203.md)
- Enumerate which characters each layer decodes; reserved chars that survive the filter but are decoded later are the bypass set [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-qcxp-gm7m-4j5v.md)
- Are alternate path forms (backslash, UNC, device paths, matrix params) canonicalized before the check? [E4](https://bugbountylibrary.com/r/h1%3A150976.md)
- Prefer canonicalize-once-then-compare over re-parsing downstream.

## Variants seen
- Parser differential: regex authority terminator vs. browser's [E1](https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2020-03-08-the-unexpected-google-wide-domain-check-bypass.md)
- Double decoding of userinfo vs. ACL regex [E2](https://bugbountylibrary.com/r/h1%3A824203.md)
- Partial vs. full percent-decoding plus matrix-param smuggling [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-qcxp-gm7m-4j5v.md)
- Unnormalized UNC/device path bypassing a sandbox rule [E4](https://bugbountylibrary.com/r/h1%3A150976.md)

## Impact and severity
Led to API key theft via postMessage [E1](https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2020-03-08-the-unexpected-google-wide-domain-check-bypass.md), unauthenticated access to internal manager pages leaking client info and memory addresses [E2](https://bugbountylibrary.com/r/h1%3A824203.md), unauthenticated access to protected static files [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-qcxp-gm7m-4j5v.md), and local file read from a sandboxed SWF [E4](https://bugbountylibrary.com/r/h1%3A150976.md). Severity rises when the bypass reaches secrets, internal endpoints, or filesystem access, and when the differential is reachable pre-auth.

## Why fixes fail
Fixing only the checker's regex leaves the downstream decoder unchanged; the two must be reconciled, since the gap is the disagreement, not either parser alone [E1](https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2020-03-08-the-unexpected-google-wide-domain-check-bypass.md)[E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-qcxp-gm7m-4j5v.md).

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2020-03-08-the-unexpected-google-wide-domain-check-bypass.md
- E2: https://bugbountylibrary.com/r/h1%3A824203.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-qcxp-gm7m-4j5v.md
- E4: https://bugbountylibrary.com/r/h1%3A150976.md
