Basic Auth credentials passed via URL are not URL-decoded before encoding to Base64
Closed this issue · 0 comments
Hello,
Hackney allows you to pass basic auth credentials via a URL like this: http://Aladdin:open@example.com
. These credentials are properly translated into a basic auth header like Authorization: Basic QWxhZGRpbjpvcGVu
, which is sent with the request.
However, when a URL-encoded username or password is given, the resulting Authorization
header is incorrect, because the username and password are not URL-decoded by Hackney before they are base64 encoded for the Authorization
header. For example, the URL http://Aladdin:open%20sesame@example.com
results in the following header: Authorization: Basic QWxhZGRpbjpvcGVuJTIwc2VzYW1l
. When you base64 decode that header, you get Aladdin:open%20sesame
.
This exact example is used in the HTTP Basic Auth RFC, where it shows that the correct header is actually Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
.
I suspect this bug is present because hackney_url
does not URL-decode the user/pass, but I'm not sure if this is the right place to fix it:
iex(24)> :hackney_url.parse_url("https://Aladdin:open%20sesame@example.com")
{:hackney_url, :hackney_ssl, :https, "example.com", "", "/", "", "",
'example.com', 443, "Aladdin", "open%20sesame"}
Until this is fixed, my workaround is to manually extract the user/pass from the URL before passing it to Hackney, URL-decoding myself, and passing the decoded user/pass via the basic_auth
options.