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: #31439

PR-URL: #39310
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
Lew Gordon authored and targos committed Sep 4, 2021
1 parent a437de3 commit 2bc301d
Show file tree
Hide file tree
Showing 4 changed files with 57 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 @@ -2767,6 +2767,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: v14.17.0
pr-url: https://github.com/nodejs/node/pull/36048
description: It is possible to abort a request with an AbortSignal.
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
pr-url: https://github.com/nodejs/node/pull/32786
description: The `highWaterMark` option is accepted now.
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
48 changes: 48 additions & 0 deletions test/parallel/test-http-decoded-auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'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) {
const server = http.createServer(function(request, response) {
// The correct authorization header is be passed
assert.strictEqual(request.headers.authorization, `Basic ${testCase.expected}`);
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 2bc301d

Please sign in to comment.