Skip to content

Commit 861ccd9

Browse files
authoredMay 25, 2022
Disable redirects to UNIX sockets (sindresorhus#2047)
1 parent 4cdcca3 commit 861ccd9

File tree

4 files changed

+57
-1
lines changed

4 files changed

+57
-1
lines changed
 

‎source/core/index.ts

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import calculateRetryDelay from './calculate-retry-delay.js';
2323
import Options, {OptionsError, OptionsInit} from './options.js';
2424
import {isResponseOk, Response} from './response.js';
2525
import isClientRequest from './utils/is-client-request.js';
26+
import isUnixSocketURL from './utils/is-unix-socket-url.js';
2627
import {
2728
RequestError,
2829
ReadError,
@@ -727,6 +728,11 @@ export default class Request extends Duplex implements RequestEvents<Request> {
727728
const redirectBuffer = Buffer.from(response.headers.location, 'binary').toString();
728729
const redirectUrl = new URL(redirectBuffer, url);
729730

731+
if (!isUnixSocketURL(url as URL) && isUnixSocketURL(redirectUrl)) {
732+
this._beforeError(new RequestError('Cannot redirect to UNIX socket', {}, this));
733+
return;
734+
}
735+
730736
// Redirecting to a different site, clear sensitive data.
731737
if (redirectUrl.hostname !== (url as URL).hostname || redirectUrl.port !== (url as URL).port) {
732738
if ('host' in updatedOptions.headers) {
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import {URL} from 'url';
2+
3+
// eslint-disable-next-line @typescript-eslint/naming-convention
4+
export default function isUnixSocketURL(url: URL) {
5+
return url.protocol === 'unix:' || url.hostname === 'unix';
6+
}

‎test/redirects.ts

+30-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {Buffer} from 'buffer';
22
import test from 'ava';
33
import {Handler} from 'express';
44
import nock from 'nock';
5-
import got, {MaxRedirectsError} from '../source/index.js';
5+
import got, {MaxRedirectsError, RequestError} from '../source/index.js';
66
import withServer, {withHttpsServer} from './helpers/with-server.js';
77

88
const reachedHandler: Handler = (_request, response) => {
@@ -28,6 +28,35 @@ const relativeHandler: Handler = (_request, response) => {
2828
response.end();
2929
};
3030

31+
const unixProtocol: Handler = (_request, response) => {
32+
response.writeHead(302, {
33+
location: 'unix:/var/run/docker.sock:/containers/json',
34+
});
35+
response.end();
36+
};
37+
38+
const unixHostname: Handler = (_request, response) => {
39+
response.writeHead(302, {
40+
location: 'http://unix:/var/run/docker.sock:/containers/json',
41+
});
42+
response.end();
43+
};
44+
45+
test('cannot redirect to unix protocol', withServer, async (t, server, got) => {
46+
server.get('/protocol', unixProtocol);
47+
server.get('/hostname', unixHostname);
48+
49+
await t.throwsAsync(got('protocol'), {
50+
message: 'Cannot redirect to UNIX socket',
51+
instanceOf: RequestError,
52+
});
53+
54+
await t.throwsAsync(got('hostname'), {
55+
message: 'Cannot redirect to UNIX socket',
56+
instanceOf: RequestError,
57+
});
58+
});
59+
3160
test('follows redirect', withServer, async (t, server, got) => {
3261
server.get('/', reachedHandler);
3362
server.get('/finite', finiteHandler);

‎test/unix-socket.ts

+15
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ const okHandler: Handler = (_request, response) => {
99
response.end('ok');
1010
};
1111

12+
const redirectHandler: Handler = (_request, response) => {
13+
response.writeHead(302, {
14+
location: 'foo',
15+
});
16+
response.end();
17+
};
18+
1219
if (process.platform !== 'win32') {
1320
test('works', withSocketServer, async (t, server) => {
1421
server.on('/', okHandler);
@@ -53,4 +60,12 @@ if (process.platform !== 'win32') {
5360
const url = format('http://unix:%s:%s', server.socketPath, '/?a=1');
5461
t.is((await got(url)).body, 'ok');
5562
});
63+
64+
test('redirects work', withSocketServer, async (t, server) => {
65+
server.on('/', redirectHandler);
66+
server.on('/foo', okHandler);
67+
68+
const url = format('http://unix:%s:%s', server.socketPath, '/');
69+
t.is((await got(url)).body, 'ok');
70+
});
5671
}

0 commit comments

Comments
 (0)
Please sign in to comment.