From bce8ce7d528a675bd5a8d996e110b73674e290d2 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 26 May 2022 01:36:12 +0700 Subject: [PATCH] Backport 861ccd9ac2237df762a9e2beed7edd88c60782dc --- source/core/index.ts | 10 ++++++++++ test/redirects.ts | 31 ++++++++++++++++++++++++++++++- test/unix-socket.ts | 15 +++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/source/core/index.ts b/source/core/index.ts index a2aa37e54..bec7192fc 100644 --- a/source/core/index.ts +++ b/source/core/index.ts @@ -2100,6 +2100,16 @@ export default class Request extends Duplex implements RequestEvents { const redirectString = redirectUrl.toString(); decodeURI(redirectString); + // eslint-disable-next-line no-inner-declarations + function isUnixSocketURL(url: URL) { + return url.protocol === 'unix:' || url.hostname === 'unix'; + } + + if (!isUnixSocketURL(url) && isUnixSocketURL(redirectUrl)) { + this._beforeError(new RequestError('Cannot redirect to UNIX socket', {}, this)); + return; + } + // Redirecting to a different site, clear sensitive data. if (redirectUrl.hostname !== url.hostname || redirectUrl.port !== url.port) { if ('host' in options.headers) { diff --git a/test/redirects.ts b/test/redirects.ts index 57f79b875..ff0a78332 100644 --- a/test/redirects.ts +++ b/test/redirects.ts @@ -1,7 +1,7 @@ import test from 'ava'; import {Handler} from 'express'; import nock = require('nock'); -import got, {MaxRedirectsError} from '../source'; +import got, {MaxRedirectsError, RequestError} from '../source'; import withServer, {withHttpsServer} from './helpers/with-server'; const reachedHandler: Handler = (_request, response) => { @@ -509,3 +509,32 @@ test('correct port on redirect', withServer, async (t, server1, got) => { t.is(response.body, 'SERVER2'); }); }); + +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 + }); +}); diff --git a/test/unix-socket.ts b/test/unix-socket.ts index 99a8beb11..66e7fed81 100644 --- a/test/unix-socket.ts +++ b/test/unix-socket.ts @@ -8,6 +8,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); @@ -53,3 +60,11 @@ if (process.platform !== 'win32') { 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'); +});