Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions source/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,11 @@ export default class Request extends Duplex implements RequestEvents<Request> {
const redirectBuffer = Buffer.from(response.headers.location, 'binary').toString();
const redirectUrl = new URL(redirectBuffer, url);

if ((url as URL).hostname !== 'unix' && (redirectUrl.protocol === 'unix:' || redirectUrl.hostname === 'unix')) {
this._beforeError(new RequestError('Cannot redirect to UNIX socket', {}, this));
return;
}

// Redirecting to a different site, clear sensitive data.
if (redirectUrl.hostname !== (url as URL).hostname || redirectUrl.port !== (url as URL).port) {
if ('host' in updatedOptions.headers) {
Expand Down
31 changes: 30 additions & 1 deletion test/redirects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {Buffer} from 'buffer';
import test from 'ava';
import {Handler} from 'express';
import nock from 'nock';
import got, {MaxRedirectsError} from '../source/index.js';
import got, {MaxRedirectsError, RequestError} from '../source/index.js';
import withServer, {withHttpsServer} from './helpers/with-server.js';

const reachedHandler: Handler = (_request, response) => {
Expand All @@ -28,6 +28,35 @@ const relativeHandler: Handler = (_request, response) => {
response.end();
};

const unixProtocol: Handler = (_request, response) => {
response.writeHead(302, {
location: 'unix:/var/run/docker.sock:/containers/json',
});
response.end();
};

const unixHostname: Handler = (_request, response) => {
response.writeHead(302, {
location: 'http://unix:/var/run/docker.sock:/containers/json',
});
response.end();
};

test('cannot redirect to unix protocol', withServer, async (t, server, got) => {
server.get('/protocol', unixProtocol);
server.get('/hostname', unixHostname);

await t.throwsAsync(got('protocol'), {
message: 'Cannot redirect to UNIX socket',
instanceOf: RequestError,
});

await t.throwsAsync(got('hostname'), {
message: 'Cannot redirect to UNIX socket',
instanceOf: RequestError,
});
});

test('follows redirect', withServer, async (t, server, got) => {
server.get('/', reachedHandler);
server.get('/finite', finiteHandler);
Expand Down
15 changes: 15 additions & 0 deletions test/unix-socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ const okHandler: Handler = (_request, response) => {
response.end('ok');
};

const redirectHandler: Handler = (_request, response) => {
response.writeHead(302, {
location: 'foo',
});
response.end();
};

if (process.platform !== 'win32') {
test('works', withSocketServer, async (t, server) => {
server.on('/', okHandler);
Expand Down Expand Up @@ -53,4 +60,12 @@ if (process.platform !== 'win32') {
const url = format('http://unix:%s:%s', server.socketPath, '/?a=1');
t.is((await got(url)).body, 'ok');
});

test('redirects work', withSocketServer, async (t, server) => {
server.on('/', redirectHandler);
server.on('/foo', okHandler);

const url = format('http://unix:%s:%s', server.socketPath, '/');
t.is((await got(url)).body, 'ok');
});
}