Skip to content

Commit fce5303

Browse files
Lew Gordonjasnell
Lew Gordon
authored andcommitted
http: decodes url.username and url.password for authorization header
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 <[email protected]> Reviewed-By: Robert Nagy <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 7f167f4 commit fce5303

File tree

4 files changed

+57
-1
lines changed

4 files changed

+57
-1
lines changed

doc/api/http.md

+4
Original file line numberDiff line numberDiff line change
@@ -2835,6 +2835,10 @@ This can be overridden for servers and client requests by passing the
28352835
<!-- YAML
28362836
added: v0.3.6
28372837
changes:
2838+
- version: REPLACEME
2839+
pr-url: https://github.com/nodejs/node/pull/39310
2840+
description: When using a `URL` object parsed username and
2841+
password will now be properly URI decoded.
28382842
- version:
28392843
- v15.3.0
28402844
- v14.17.0

doc/api/https.md

+4
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,10 @@ Global instance of [`https.Agent`][] for all HTTPS client requests.
251251
<!-- YAML
252252
added: v0.3.6
253253
changes:
254+
- version: REPLACEME
255+
pr-url: https://github.com/nodejs/node/pull/39310
256+
description: When using a `URL` object parsed username
257+
and password will now be properly URI decoded.
254258
- version:
255259
- v14.1.0
256260
- v13.14.0

lib/internal/url.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1303,7 +1303,7 @@ function urlToHttpOptions(url) {
13031303
options.port = Number(url.port);
13041304
}
13051305
if (url.username || url.password) {
1306-
options.auth = `${url.username}:${url.password}`;
1306+
options.auth = `${decodeURIComponent(url.username)}:${decodeURIComponent(url.password)}`;
13071307
}
13081308
return options;
13091309
}
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('assert');
4+
const http = require('http');
5+
6+
const testCases = [
7+
{
8+
username: 'test@test"',
9+
password: '123456^',
10+
expected: 'dGVzdEB0ZXN0IjoxMjM0NTZe'
11+
},
12+
{
13+
username: 'test%40test',
14+
password: '123456',
15+
expected: 'dGVzdEB0ZXN0OjEyMzQ1Ng=='
16+
},
17+
{
18+
username: 'not%3Agood',
19+
password: 'god',
20+
expected: 'bm90Omdvb2Q6Z29k'
21+
},
22+
{
23+
username: 'not%22good',
24+
password: 'g%5Eod',
25+
expected: 'bm90Imdvb2Q6Z15vZA=='
26+
},
27+
{
28+
username: 'test1234::::',
29+
password: 'mypass',
30+
expected: 'dGVzdDEyMzQ6Ojo6Om15cGFzcw=='
31+
},
32+
];
33+
34+
for (const testCase of testCases) {
35+
const server = http.createServer(function(request, response) {
36+
// The correct authorization header is be passed
37+
assert.strictEqual(request.headers.authorization, `Basic ${testCase.expected}`);
38+
response.writeHead(200, {});
39+
response.end('ok');
40+
server.close();
41+
});
42+
43+
server.listen(0, function() {
44+
// make the request
45+
const url = new URL(`http://${testCase.username}:${testCase.password}@localhost:${this.address().port}`);
46+
http.request(url).end();
47+
});
48+
}

0 commit comments

Comments
 (0)