| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2153,6 +2153,12 @@ An attempt was made to open an IPC communication channel with a synchronously | |||
| 2153 | 2153 | forked Node.js process. See the documentation for the [`child_process`][] module | |
| 2154 | 2154 | for more information. | |
| 2155 | 2155 | ||
| 2156 | + <a id="ERR_IP_BLOCKED"></a> | ||
| 2157 | + | ||
| 2158 | + ### `ERR_IP_BLOCKED` | ||
| 2159 | + | ||
| 2160 | + IP is blocked by `net.BlockList`. | ||
| 2161 | + | ||
| 2156 | 2162 | <a id="ERR_LOADER_CHAIN_INCOMPLETE"></a> | |
| 2157 | 2163 | ||
| 2158 | 2164 | ### `ERR_LOADER_CHAIN_INCOMPLETE` | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1089,6 +1089,8 @@ For TCP connections, available `options` are: | |||
| 1089 | 1089 | * `noDelay` {boolean} If set to `true`, it disables the use of Nagle's algorithm | |
| 1090 | 1090 | immediately after the socket is established. **Default:** `false`. | |
| 1091 | 1091 | * `port` {number} Required. Port the socket should connect to. | |
| 1092 | + * `blockList` {net.BlockList} `blockList` can be used for disabling outbound | ||
| 1093 | + access to specific IP addresses, IP ranges, or IP subnets. | ||
| 1092 | 1094 | ||
| 1093 | 1095 | For [IPC][] connections, available `options` are: | |
| 1094 | 1096 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1551,6 +1551,9 @@ E('ERR_IPC_CHANNEL_CLOSED', 'Channel closed', Error); | |||
| 1551 | 1551 | E('ERR_IPC_DISCONNECTED', 'IPC channel is already disconnected', Error); | |
| 1552 | 1552 | E('ERR_IPC_ONE_PIPE', 'Child process can have only one IPC pipe', Error); | |
| 1553 | 1553 | E('ERR_IPC_SYNC_FORK', 'IPC cannot be used with synchronous forks', Error); | |
| 1554 | + E('ERR_IP_BLOCKED', function(ip) { | ||
| 1555 | + return `IP(${ip}) is blocked by net.BlockList`; | ||
| 1556 | + }, Error); | ||
| 1554 | 1557 | E( | |
| 1555 | 1558 | 'ERR_LOADER_CHAIN_INCOMPLETE', | |
| 1556 | 1559 | '"%s" did not call the next hook in its chain and did not' + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -105,6 +105,7 @@ const { | |||
| 105 | 105 | ERR_INVALID_FD_TYPE, | |
| 106 | 106 | ERR_INVALID_HANDLE_TYPE, | |
| 107 | 107 | ERR_INVALID_IP_ADDRESS, | |
| 108 | + ERR_IP_BLOCKED, | ||
| 108 | 109 | ERR_MISSING_ARGS, | |
| 109 | 110 | ERR_SERVER_ALREADY_LISTEN, | |
| 110 | 111 | ERR_SERVER_NOT_RUNNING, | |
@@ -510,6 +511,12 @@ function Socket(options) { | |||
| 510 | 511 | // Used after `.destroy()` | |
| 511 | 512 | this[kBytesRead] = 0; | |
| 512 | 513 | this[kBytesWritten] = 0; | |
| 514 | + if (options.blockList) { | ||
| 515 | + if (!module.exports.BlockList.isBlockList(options.blockList)) { | ||
| 516 | + throw new ERR_INVALID_ARG_TYPE('options.blockList', 'net.BlockList', options.blockList); | ||
| 517 | + } | ||
| 518 | + this.blockList = options.blockList; | ||
| 519 | + } | ||
| 513 | 520 | } | |
| 514 | 521 | ObjectSetPrototypeOf(Socket.prototype, stream.Duplex.prototype); | |
| 515 | 522 | ObjectSetPrototypeOf(Socket, stream.Duplex); | |
@@ -1073,6 +1080,10 @@ function internalConnect( | |||
| 1073 | 1080 | self.emit('connectionAttempt', address, port, addressType); | |
| 1074 | 1081 | ||
| 1075 | 1082 | if (addressType === 6 || addressType === 4) { | |
| 1083 | + if (self.blockList?.check(address, `ipv${addressType}`)) { | ||
| 1084 | + self.destroy(new ERR_IP_BLOCKED(address)); | ||
| 1085 | + return; | ||
| 1086 | + } | ||
| 1076 | 1087 | const req = new TCPConnectWrap(); | |
| 1077 | 1088 | req.oncomplete = afterConnect; | |
| 1078 | 1089 | req.address = address; | |
@@ -1162,6 +1173,14 @@ function internalConnectMultiple(context, canceled) { | |||
| 1162 | 1173 | } | |
| 1163 | 1174 | } | |
| 1164 | 1175 | ||
| 1176 | + if (self.blockList?.check(address, `ipv${addressType}`)) { | ||
| 1177 | + const ex = new ERR_IP_BLOCKED(address); | ||
| 1178 | + ArrayPrototypePush(context.errors, ex); | ||
| 1179 | + self.emit('connectionAttemptFailed', address, port, addressType, ex); | ||
| 1180 | + internalConnectMultiple(context); | ||
| 1181 | + return; | ||
| 1182 | + } | ||
| 1183 | + | ||
| 1165 | 1184 | debug('connect/multiple: attempting to connect to %s:%d (addressType: %d)', address, port, addressType); | |
| 1166 | 1185 | self.emit('connectionAttempt', address, port, addressType); | |
| 1167 | 1186 | ||
@@ -1792,8 +1811,7 @@ function Server(options, connectionListener) { | |||
| 1792 | 1811 | this.keepAliveInitialDelay = ~~(options.keepAliveInitialDelay / 1000); | |
| 1793 | 1812 | this.highWaterMark = options.highWaterMark ?? getDefaultHighWaterMark(); | |
| 1794 | 1813 | if (options.blockList) { | |
| 1795 | - // TODO: use BlockList.isBlockList (https://github.com/nodejs/node/pull/56078) | ||
| 1796 | - if (!(options.blockList instanceof module.exports.BlockList)) { | ||
| 1814 | + if (!module.exports.BlockList.isBlockList(options.blockList)) { | ||
| 1797 | 1815 | throw new ERR_INVALID_ARG_TYPE('options.blockList', 'net.BlockList', options.blockList); | |
| 1798 | 1816 | } | |
| 1799 | 1817 | this.blockList = options.blockList; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,68 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + const net = require('net'); | ||
| 5 | + const assert = require('assert'); | ||
| 6 | + | ||
| 7 | + const blockList = new net.BlockList(); | ||
| 8 | + blockList.addAddress('127.0.0.1'); | ||
| 9 | + blockList.addAddress('127.0.0.2'); | ||
| 10 | + | ||
| 11 | + function check(err) { | ||
| 12 | + assert.ok(err.code === 'ERR_IP_BLOCKED', err); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + // Connect without calling dns.lookup | ||
| 16 | + { | ||
| 17 | + const socket = net.connect({ | ||
| 18 | + port: 9999, | ||
| 19 | + host: '127.0.0.1', | ||
| 20 | + blockList, | ||
| 21 | + }); | ||
| 22 | + socket.on('error', common.mustCall(check)); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + // Connect with single IP returned by dns.lookup | ||
| 26 | + { | ||
| 27 | + const socket = net.connect({ | ||
| 28 | + port: 9999, | ||
| 29 | + host: 'localhost', | ||
| 30 | + blockList, | ||
| 31 | + lookup: function(_, __, cb) { | ||
| 32 | + cb(null, '127.0.0.1', 4); | ||
| 33 | + }, | ||
| 34 | + autoSelectFamily: false, | ||
| 35 | + }); | ||
| 36 | + | ||
| 37 | + socket.on('error', common.mustCall(check)); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + // Connect with autoSelectFamily and single IP | ||
| 41 | + { | ||
| 42 | + const socket = net.connect({ | ||
| 43 | + port: 9999, | ||
| 44 | + host: 'localhost', | ||
| 45 | + blockList, | ||
| 46 | + lookup: function(_, __, cb) { | ||
| 47 | + cb(null, [{ address: '127.0.0.1', family: 4 }]); | ||
| 48 | + }, | ||
| 49 | + autoSelectFamily: true, | ||
| 50 | + }); | ||
| 51 | + | ||
| 52 | + socket.on('error', common.mustCall(check)); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + // Connect with autoSelectFamily and multiple IPs | ||
| 56 | + { | ||
| 57 | + const socket = net.connect({ | ||
| 58 | + port: 9999, | ||
| 59 | + host: 'localhost', | ||
| 60 | + blockList, | ||
| 61 | + lookup: function(_, __, cb) { | ||
| 62 | + cb(null, [{ address: '127.0.0.1', family: 4 }, { address: '127.0.0.2', family: 4 }]); | ||
| 63 | + }, | ||
| 64 | + autoSelectFamily: true, | ||
| 65 | + }); | ||
| 66 | + | ||
| 67 | + socket.on('error', common.mustCall(check)); | ||
| 68 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments