Skip to content

Commit

Permalink
http: decodes url.username and url.password for authorization header
Browse files Browse the repository at this point in the history
This change properly decodes the url.username and url.password for
the authorization header constructed from the URL object for
http(s) requests.

Fixes: nodejs#31439
  • Loading branch information
Lew Gordon committed Jul 15, 2021
1 parent 82b1b55 commit 8d1096c
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 1 deletion.
4 changes: 4 additions & 0 deletions doc/api/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -2804,6 +2804,10 @@ This can be overridden for servers and client requests by passing the
<!-- YAML
added: v0.3.6
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/39310
description: When using a `URL` object parsed username and
password will now be properly URI decoded.
- version:
- v15.3.0
- v14.17.0
Expand Down
4 changes: 4 additions & 0 deletions doc/api/https.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ Global instance of [`https.Agent`][] for all HTTPS client requests.
<!-- YAML
added: v0.3.6
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/39310
description: When using a `URL` object parsed username
and password will now be properly URI decoded.
- version:
- v14.1.0
- v13.14.0
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -1303,7 +1303,7 @@ function urlToHttpOptions(url) {
options.port = Number(url.port);
}
if (url.username || url.password) {
options.auth = `${url.username}:${url.password}`;
options.auth = `${decodeURIComponent(url.username)}:${decodeURIComponent(url.password)}`;
}
return options;
}
Expand Down
33 changes: 33 additions & 0 deletions test/parallel/test-http-decoded-auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';
require('../common');
const assert = require('assert');
const http = require('http');

const testCases = [
{username: 'test@test"', password: '123456^', expected: 'dGVzdEB0ZXN0IjoxMjM0NTZe'},
{username: 'test%40test', password: '123456', expected: 'dGVzdEB0ZXN0OjEyMzQ1Ng=='},
{username: 'not%3Agood', password: 'god', expected: 'bm90Omdvb2Q6Z29k'},
{username: 'not%22good', password: 'g%5Eod', expected: 'bm90Imdvb2Q6Z15vZA=='},
{username: 'test1234::::', password: 'mypass', expected: 'dGVzdDEyMzQ6Ojo6Om15cGFzcw=='}
]

for (const testCase of testCases) {
function check(request) {
// The correct authorization header is be passed
assert.strictEqual(request.headers.authorization, `Basic ${testCase.expected}`);
}

const server = http.createServer(function(request, response) {
// Run the check function
check(request);
response.writeHead(200, {});
response.end('ok');
server.close();
});

server.listen(0, function() {
// make the request
const url = new URL(`http://${testCase.username}:${testCase.password}@localhost:${this.address().port}`);
http.request(url).end();
});
}

0 comments on commit 8d1096c

Please sign in to comment.