diff --git a/documentation/2-options.md b/documentation/2-options.md
index ac8f9eb07..8969a2a11 100644
--- a/documentation/2-options.md
+++ b/documentation/2-options.md
@@ -918,6 +918,37 @@ By default, requests will not use [method rewriting](https://datatracker.ietf.or
For example, when sending a `POST` request and receiving a `302`, it will resend the body to the new location using the same HTTP method (`POST` in this case). To rewrite the request as `GET`, set this option to `true`.
+### `enableUnixSockets`
+
+**Type: `boolean`**\
+**Default: `true`**
+
+When enabled, requests can also be sent via [UNIX Domain Sockets](https://serverfault.com/questions/124517/what-is-the-difference-between-unix-sockets-and-tcp-ip-sockets). Please note that in the upcoming major release (Got v13) this default will be changed to `false` for security reasons.
+
+> **Warning**
+> Make sure you do your own URL sanitizing if you accept untrusted user input for the URL.
+
+Use the following URL scheme: `PROTOCOL://unix:SOCKET:PATH`
+
+- `PROTOCOL` - `http` or `https`
+- `SOCKET` - Absolute path to a UNIX domain socket, for example: `/var/run/docker.sock`
+- `PATH` - Request path, for example: `/v2/keys`
+
+```js
+import got from 'got';
+
+await got('http://unix:/var/run/docker.sock:/containers/json', {enableUnixSockets: true});
+
+// Or without protocol (HTTP by default)
+await got('unix:/var/run/docker.sock:/containers/json', {enableUnixSockets: true});
+
+// Disable Unix sockets
+const gotUnixSocketsDisabled = got.extend({enableUnixSockets: false});
+
+// RequestError: Using UNIX domain sockets but option `enableUnixSockets` is not enabled
+await gotUnixSocketsDisabled('http://unix:/var/run/docker.sock:/containers/json');
+```
+
## Methods
### `options.merge(other: Options | OptionsInit)`
diff --git a/documentation/migration-guides/axios.md b/documentation/migration-guides/axios.md
index f4a457291..a17f606df 100644
--- a/documentation/migration-guides/axios.md
+++ b/documentation/migration-guides/axios.md
@@ -24,7 +24,7 @@ We deeply care about readability, so we renamed these options:
- `httpAgent` → [`agent.http`](../2-options.md#agent)
- `httpsAgent` → [`agent.https`](../2-options.md#agent)
-- `socketPath` → [`url`](../tips.md#unix)
+- `socketPath` → [`url`](../2-options.md#enableunixsockets)
- `responseEncoding` → [`encoding`](../2-options.md#encoding)
- `auth.username` → [`username`](../2-options.md#username)
- `auth.password` → [`password`](../2-options.md#password)
diff --git a/documentation/migration-guides/request.md b/documentation/migration-guides/request.md
index b34329424..b6e80bea6 100644
--- a/documentation/migration-guides/request.md
+++ b/documentation/migration-guides/request.md
@@ -46,7 +46,7 @@ These Got options are the same as with Request:
- [`localAddress`](../2-options.md#localaddress)
- [`headers`](../2-options.md#headers)
- [`createConnection`](../2-options.md#createconnection)
-- [UNIX sockets](../tips.md#unixsockets): `http://unix:SOCKET:PATH`
+- [UNIX sockets](../2-options.md#enableunixsockets): `http://unix:SOCKET:PATH`
The `time` option does not exist, assume [it's always true](../6-timeout.md).
diff --git a/documentation/tips.md b/documentation/tips.md
index 014a28d94..1058e4188 100644
--- a/documentation/tips.md
+++ b/documentation/tips.md
@@ -92,21 +92,7 @@ for await (const commitData of pagination) {
### UNIX Domain Sockets
-Requests can also be sent via [UNIX Domain Sockets](https://serverfault.com/questions/124517/what-is-the-difference-between-unix-sockets-and-tcp-ip-sockets).\
-Use the following URL scheme: `PROTOCOL://unix:SOCKET:PATH`
-
-- `PROTOCOL` - `http` or `https`
-- `SOCKET` - Absolute path to a unix domain socket, for example: `/var/run/docker.sock`
-- `PATH` - Request path, for example: `/v2/keys`
-
-```js
-import got from 'got';
-
-await got('http://unix:/var/run/docker.sock:/containers/json');
-
-// Or without protocol (HTTP by default)
-await got('unix:/var/run/docker.sock:/containers/json');
-```
+See the [`enableUnixSockets` option](./2-options.md#enableunixsockets).
### Testing
diff --git a/readme.md b/readme.md
index 36bed42f2..8a71857ff 100644
--- a/readme.md
+++ b/readme.md
@@ -202,7 +202,7 @@ For advanced JSON usage, check out the [`parseJson`](documentation/2-options.md#
- [x] [RFC compliant caching](documentation/cache.md)
- [x] [Proxy support](documentation/tips.md#proxying)
-- [x] [Unix Domain Sockets](documentation/tips.md#unix)
+- [x] [Unix Domain Sockets](documentation/2-options.md#enableunixsockets)
#### Integration
diff --git a/source/core/options.ts b/source/core/options.ts
index fdcabe15f..105f2b7a8 100644
--- a/source/core/options.ts
+++ b/source/core/options.ts
@@ -827,6 +827,7 @@ const defaultInternals: Options['_internals'] = {
},
setHost: true,
maxHeaderSize: undefined,
+ enableUnixSockets: true,
};
const cloneInternals = (internals: typeof defaultInternals) => {
@@ -1428,6 +1429,10 @@ export default class Options {
}
if (url.hostname === 'unix') {
+ if (!this._internals.enableUnixSockets) {
+ throw new Error('Using UNIX domain sockets but option `enableUnixSockets` is not enabled');
+ }
+
const matches = /(?.+?):(?.+)/.exec(`${url.pathname}${url.search}`);
if (matches?.groups) {
@@ -2345,6 +2350,16 @@ export default class Options {
this._internals.maxHeaderSize = value;
}
+ get enableUnixSockets() {
+ return this._internals.enableUnixSockets;
+ }
+
+ set enableUnixSockets(value: boolean) {
+ assert.boolean(value);
+
+ this._internals.enableUnixSockets = value;
+ }
+
// eslint-disable-next-line @typescript-eslint/naming-convention
toJSON() {
return {...this._internals};
diff --git a/test/redirects.ts b/test/redirects.ts
index ae2345006..96f1f65c8 100644
--- a/test/redirects.ts
+++ b/test/redirects.ts
@@ -42,10 +42,12 @@ const unixHostname: Handler = (_request, response) => {
response.end();
};
-test('cannot redirect to unix protocol', withServer, async (t, server, got) => {
+test('cannot redirect to UNIX protocol when UNIX sockets are enabled', withServer, async (t, server, got) => {
server.get('/protocol', unixProtocol);
server.get('/hostname', unixHostname);
+ t.true(got.defaults.options.enableUnixSockets);
+
await t.throwsAsync(got('protocol'), {
message: 'Cannot redirect to UNIX socket',
instanceOf: RequestError,
@@ -57,6 +59,25 @@ test('cannot redirect to unix protocol', withServer, async (t, server, got) => {
});
});
+test('cannot redirect to UNIX protocol when UNIX sockets are not enabled', withServer, async (t, server, got) => {
+ server.get('/protocol', unixProtocol);
+ server.get('/hostname', unixHostname);
+
+ const gotUnixSocketsDisabled = got.extend({enableUnixSockets: false});
+
+ t.false(gotUnixSocketsDisabled.defaults.options.enableUnixSockets);
+
+ await t.throwsAsync(gotUnixSocketsDisabled('protocol'), {
+ message: 'Cannot redirect to UNIX socket',
+ instanceOf: RequestError,
+ });
+
+ await t.throwsAsync(gotUnixSocketsDisabled('hostname'), {
+ message: 'Cannot redirect to UNIX socket',
+ instanceOf: RequestError,
+ });
+});
+
test('follows redirect', withServer, async (t, server, got) => {
server.get('/', reachedHandler);
server.get('/finite', finiteHandler);
diff --git a/test/unix-socket.ts b/test/unix-socket.ts
index 059785ea7..4523ec76f 100644
--- a/test/unix-socket.ts
+++ b/test/unix-socket.ts
@@ -68,4 +68,29 @@ if (process.platform !== 'win32') {
const url = format('http://unix:%s:%s', server.socketPath, '/');
t.is((await got(url)).body, 'ok');
});
+
+ test('`unix:` fails when UNIX sockets are not enabled', async t => {
+ const gotUnixSocketsDisabled = got.extend({enableUnixSockets: false});
+
+ t.false(gotUnixSocketsDisabled.defaults.options.enableUnixSockets);
+ await t.throwsAsync(
+ gotUnixSocketsDisabled('unix:'),
+ {
+ message: 'Using UNIX domain sockets but option `enableUnixSockets` is not enabled',
+ },
+ );
+ });
+
+ test('`http://unix:/` fails when UNIX sockets are not enabled', async t => {
+ const gotUnixSocketsDisabled = got.extend({enableUnixSockets: false});
+
+ t.false(gotUnixSocketsDisabled.defaults.options.enableUnixSockets);
+
+ await t.throwsAsync(
+ gotUnixSocketsDisabled('http://unix:'),
+ {
+ message: 'Using UNIX domain sockets but option `enableUnixSockets` is not enabled',
+ },
+ );
+ });
}