Skip to content
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

Request with basic auth does not work when passwords include umlaut #2133

Open
maros opened this issue Nov 27, 2023 · 4 comments
Open

Request with basic auth does not work when passwords include umlaut #2133

maros opened this issue Nov 27, 2023 · 4 comments

Comments

@maros
Copy link

maros commented Nov 27, 2023

  • Mojolicious version: 9.35.
  • Perl version: 5.38.0
  • Operating system: debian 12.2

Steps to reproduce the behavior

Basic auth does not work when passwords include umlaut.

use v5.38;
use Mojo::UserAgent;
use Test::Most;
use utf8;

my $ua = Mojo::UserAgent->new;
my $userinfo = 'testing:testöööng';

binmode *STDOUT,':utf8';
binmode *STDERR,':utf8';

foreach my $url (
    'https://testing:testöööng@outpost.geizhals.at/maro/testing',
    'https://testing:test%C3%B6%C3%B6%C3%B6ng@outpost.geizhals.at/maro/testing',
    'https://testing:test%F6%F6%F6ng@outpost.geizhals.at/maro/testing',  # not sure if this should work
    ) {
    my $tx = $ua->get($url);
    is($tx->req->url->userinfo,$userinfo,'Userinfo parsed ok');
    is($tx->res->code,200,'Code 200');
}

Same url works fine when requested via curl

curl  'https://testing:test%C3%B6%C3%B6%C3%B6ng@outpost.geizhals.at/maro/testing'
hallo

Expected behavior

Request should succeed

Actual behavior

401 error

@fskale
Copy link

fskale commented Nov 28, 2023

You should really should study the cookbook:
https://docs.mojolicious.org/Mojolicious/Guides/Cookbook
and the browse to "[Basic authentication]" ;-)
Create e new Mojo::URL Object and provide your authentication data there:
(use the env var MOJO_CLIENT_DEBUG and set it to 1 to get additional debug output).
E.g: (Minimal Script)

use Mojo::UserAgent;
use Mojo::URL;
use Test::Most;

my $ua = Mojo::UserAgent->new;
my $url = Mojo::URL->new('https://outpost.geizhals.at/maro/testing');
my $userinfo = $url->userinfo('testing:testöööng');

my $tx = $ua->get($url);
is($tx->req->url->userinfo,$userinfo,'Userinfo parsed ok');
is($tx->res->code,200,'Code 200');

@maros
Copy link
Author

maros commented Nov 28, 2023

i extended the testcase to also include explicitely created Mojo::URLs. But it also results in a 401

use v5.38;
use Mojo::UserAgent;
use Test::Most;
use utf8;

my $ua = Mojo::UserAgent->new;
my $USERINFO = 'testing:testöööng';
my $BASEURL = 'outpost.geizhals.at/maro/testing';

my $mojo_url = Mojo::URL->new("https://$BASEURL");
$mojo_url->userinfo($USERINFO);

foreach my $url (
    "https://${USERINFO}\@${BASEURL}",
    "https://testing:test%C3%B6%C3%B6%C3%B6ng\@${BASEURL}",
    "https://testing:test%F6%F6%F6ng\@${BASEURL}",
    $mojo_url
    ) {
    my $tx = $ua->get($url);
    is($tx->req->url->userinfo,$USERINFO,'Userinfo parsed ok');
    is($tx->res->code,200,'Code 200');
}

The request authorization header is the same for all four requests.

@kraih
Copy link
Member

kraih commented Nov 28, 2023

If any of this is a bug depends entirely on the specs. Please provide references to specific spec sections we are currently violating. A random internet service is not a valid test case.

@maros
Copy link
Author

maros commented Nov 28, 2023

According to RFC-7617 the encoding of the Authoritzation is undefined for backward-compatibility reasons and as long as it remains compatible with US-ASCII. The RFC suggests that it can be latin-1 or utf-8. Most server implementations and browsers nowadays seem to prefer the later.

It is possible to include a charset parameter in the Authorization header, which only accepts utf8 as the only valid value. In this case

The user's name is "test", and the password is the string "123"
followed by the Unicode character U+00A3 (POUND SIGN). Using the
character encoding scheme UTF-8, the user-pass becomes:
't' 'e' 's' 't' ':' '1' '2' '3' pound
74 65 73 74 3A 31 32 33 C2 A3
Encoding this octet sequence in Base64 ([RFC4648], Section 4) yields:
dGVzdDoxMjPCow==

The Authoritzation header from my tests contains 'dGVzdGluZzp0ZXN09vb2bmc=' which is latin-1 and not utf-8 encoded. The webserver i was testing against is a nginx/1.18.0 with no special configuration

    server {
        listen *:443 ssl;
        ssl_certificate /etc/ssl/LE/outpost.geizhals.at.fullchain.pem;
        ssl_certificate_key /etc/ssl/LE/outpost.geizhals.at.privkey.pem;
        ssl_trusted_certificate /etc/ssl/LE/outpost.geizhals.at.fullchain.pem;
        root /var/www/html;
        allow all;

        location /maro {
           auth_basic           "Maros' Reich";
           auth_basic_user_file /etc/nginx/htpasswd;
        }
    }

If you don't want to change Mojo useragent behaviour to use utf8 as default encoding, i suggest to honour the charset parameter in https://metacpan.org/pod/Mojo::UserAgent::Transactor#tx if it equals to utf-8

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

No branches or pull requests

3 participants