fix(oidc): parse loopback redirect_uri host instead of string-prefix (BUNYIP-106) #242
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/bunyip-106-loopback-redirect-uri-parse"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The authorize endpoint validated bare-loopback redirect_uris (RFC 8252) with
starts_with("http://127.0.0.1:"), sohttp://127.0.0.1:1@evil.com/cb(whose parsed host isevil.com, with127.0.0.1:1in the userinfo) andhttp://127.0.0.1.evil.com/cb(host is a subdomain ofevil.com) both passed the check. The endpoint then 302-redirected the victim's browser to the attacker host with the authorization code, an account-takeover-class leak that PKCE does not mitigate.Replace the prefix test with
redirect_uri_matches, which parses the request URI and, for bare-loopback registrations, requiresscheme == http, an empty userinfo component, and a parsed host of127.0.0.1/::1/localhost, allowing only the port and path to vary. Non-loopback clients keep byte-for-byte exact matching. Addurlto bunyip-oidc and a regression test module covering the userinfo-@and subdomain-suffix bypasses, the genuine varying-port case, the non-http scheme, and the non-loopback exact-match path.#BUNYIP-106
The authorize endpoint validated bare-loopback redirect_uris (RFC 8252) with `starts_with("http://127.0.0.1:")`, so `http://127.0.0.1:1@evil.com/cb` (whose parsed host is `evil.com`, with `127.0.0.1:1` in the userinfo) and `http://127.0.0.1.evil.com/cb` (host is a subdomain of `evil.com`) both passed the check. The endpoint then 302-redirected the victim's browser to the attacker host with the authorization code, an account-takeover-class leak that PKCE does not mitigate. Replace the prefix test with `redirect_uri_matches`, which parses the request URI and, for bare-loopback registrations, requires `scheme == http`, an empty userinfo component, and a parsed host of `127.0.0.1` / `::1` / `localhost`, allowing only the port and path to vary. Non-loopback clients keep byte-for-byte exact matching. Add `url` to bunyip-oidc and a regression test module covering the userinfo-`@` and subdomain-suffix bypasses, the genuine varying-port case, the non-http scheme, and the non-loopback exact-match path. #BUNYIP-106