-
Notifications
You must be signed in to change notification settings - Fork 393
fix: Remove urlencode from Basic Authentication header construction #466
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Reasonable - THX - please try to add a unit test - thx |
- Add test cases to verify correct handling of Basic Auth headers - Test various scenarios including: - Simple credentials - Credentials with forward slashes - Special characters - Unicode characters - Ensure compliance with RFC 2617 and RFC 7617 specifications - Validates fix for issue jumbojett#465 regarding URL-encoding of credentials Related to PR jumbojett#466
Thanks @DeepDiver1975 ! I've added unit test for the Basic Authentication header construction. The tests cover:
|
According to RFC 2617 Section 2, Basic Authentication should use base64 encoding of the raw credentials without URL encoding. This change removes the urlencode() calls that were incorrectly encoding the credentials before base64 encoding. This fixes issues with: - Special characters in client_secret being double-encoded - Non-compliance with RFC 2617 and RFC 7617 - Authentication failures with certain OpenID Connect providers
- Add test cases to verify correct handling of Basic Auth headers - Test various scenarios including: - Simple credentials - Credentials with forward slashes - Special characters - Unicode characters - Ensure compliance with RFC 2617 and RFC 7617 specifications - Validates fix for issue jumbojett#465 regarding URL-encoding of credentials Related to PR jumbojett#466
8db984e
to
08f5906
Compare
This urlencode was added in #192 as RFC 6749 (OAuth 2.0, https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1) mentions this encoding.
|
Thank you for raising this! There is indeed confusion around this point, so let’s clarify: SummaryRFC 6749 (OAuth 2.0) §2.3.1 describes two separate ways to send client credentials:
Therefore
References |
Thanks for your detailed explanation @ovsep404 I just had a look how the apache module handles it. I just looked it up on the phone and not good a C , however at first glance it looks to me like they also url encode before base64 ? |
Also this commit for the apache module OpenIDC/mod_auth_openidc@aa20bd9 and this issue for the nginx plugin zmartzone/lua-resty-openidc#204 |
Thanks for the follow-up! It’s true that some libraries like mod_auth_openidc URL-encode credentials before base64 in the Basic Auth header, but this is for compatibility with certain non-standard servers—not because the RFC requires it. Per the standards (RFC 6749, RFC 7617, and OAuth 2.0 Errata #3914), credentials in the Authorization header should NOT be URL-encoded. If there’s demand, a compatibility flag could be added, but the default should remain standards-compliant. |
How does it work if the client_id contains a
That could be a reason why RFC 6749 states:
|
The current draft of OAuth2.1 mentions this whole drama: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-2.4.1
You can follow their debate about this here: oauth-wg/oauth-v2-1#128 |
I guess we will not be able to find a solution that works for everyone. My understanding of the specs is that it should be encoded, however reality shows that is is not always done, leading to compatibilty issues. We can either extract this to a protected method anyone can overwrite, or add flags to control how to encode. |
Thank you for highlighting this edge case and referencing the OAuth 2.1 draft! It’s true that putting a colon in the client_id (e.g., a URL) creates ambiguity for HTTP Basic Auth, since per RFC 2617 the username cannot contain a colon and splitting becomes ambiguous. However, this is an unfortunate mismatch between OAuth’s flexibility for client_id and Basic Auth’s ancient constraints. Let’s be clear:
Relying on server-specific quirks is not sustainable or secure for a widely-used library. The right approach is:
Bottom line:
My proposal:
This gives users flexibility while keeping standards compliance as the default. References: |
Hi @ovsep404, I agree with you in most points, however I come to the oposite conlusion. The section in OAuth 2.1 draft §2.4.1 also mentions "Some implementations have missed the encoding step" underlining that this non RFC 7617 complianced behaivor is the OpenID-Connect complianced behaivor. Therefore the default for this libary should be with encoding, with an option to opt out, so users can be RFC 7617 compliant. |
Fixes #465
Description
This PR fixes the Basic Authentication header construction by removing the unnecessary and incorrect
urlencode()
calls. According to RFC 2617 Section 2 and RFC 7617, Basic Authentication should use base64 encoding of the raw credentials without URL encoding.Basic Authentication header construction in OpenIDConnectClient incorrectly URL-encodes the client credentials before base64 encoding them. This causes issues when client_secret contains special characters (like '/'), as they get double-encoded , they get URL-encoded (e.g., '%2F') before base64 encoding, resulting in incorrect authentication headers
Changes
urlencode()
calls from Basic Authentication header construction in:requestResourceOwnerToken
requestTokens
requestTokenExchange
refreshToken
introspectToken
revokeToken
Compliance
This change brings the implementation into compliance with:
Testing Done
Backwards Compatibility
This change may affect clients that were relying on the URL-encoded behavior, although such clients were technically not compliant with the RFC specifications.