Skip to content

Conversation

@webjunkie
Copy link

PR #1508 (wildcard support) changed redirect URI comparison to use parsed_uri.hostname instead of netloc. Since .hostname auto-lowercases, https://EXAMPLE.COM now matches https://example.com.

OAuth 2.0 Security BCP suggests exact string matching for redirect URIs - is this change intentional?

Adding a test that passes on 3.0.1 but fails on master to clarify expected behavior.

OAuth 2.0 Security Best Current Practice requires exact string matching
for redirect URI comparison. The current implementation uses urlparse's
.hostname attribute which normalizes hostnames to lowercase, causing
https://EXAMPLE.COM to incorrectly match https://example.com.

This violates the spec:
'When comparing client redirect URIs against pre-registered URIs,
authorization servers MUST utilize exact string matching.'

See: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics
@n2ygk
Copy link
Contributor

n2ygk commented Jan 8, 2026

@webjunkie Please provide a link to the BCP document section that states this.

@webjunkie
Copy link
Author

@n2ygk

Happy to provide that! So rfc9700 states in 4.1.3:

This means the authorization server MUST ensure that the two URIs are equal; see Section 6.2.1 of [RFC3986], Simple String Comparison, for details.

It only references 6.2.1, which states:

In practical terms, character-by-character comparisons should be done codepoint-by-codepoint after conversion to a common character encoding.

That does not include any normalization or case-folding (that's 6.2.2, which seems intentionally not referenced).

@dopry
Copy link
Member

dopry commented Jan 9, 2026

per RFC 3986, RFC 7230 hostnames in uris are not case sensitive. therefore a case insensitive comparison of hostname is required when checking if a uri is equal as per the RFC9700 that you reference.

@dopry dopry closed this Jan 9, 2026
@webjunkie
Copy link
Author

Thanks for the clarification. I may be missing an intended interpretation here, but I’m concerned the current behavior is no longer “exact string matching” for redirect_uri.

Multiple specs/guidance documents explicitly call for exact matching / simple string comparison for redirect URIs:

Separately, major providers document strictness in practice. For example, Microsoft Entra states redirect URIs are case-sensitive (at least for the URL path) and must match what’s configured:

If the maintainers prefer "semantic equivalence" for hostnames (case-insensitive host), could we at least:

  1. document that redirect URI host matching is intentionally case-insensitive, and
  2. consider making this behavior opt-in (since it diverges from the strict "exact string matching" guidance above)?

webjunkie added a commit to PostHog/posthog that referenced this pull request Jan 13, 2026
django-oauth-toolkit 3.1.0 introduced case-insensitive hostname
matching for redirect URIs (PR #1508), violating RFC 9700.

Upstream issue: django-oauth/django-oauth-toolkit#1632
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants