Commit 269cab63209 for nodejs
commit 269cab632090e50d75e7180ed22df773ab7fba0a
Author: Matteo Collina <hello@matteocollina.com>
Date: Sat Oct 17 11:45:08 2026 +0200
net: fail closed when BlockList peer address is unavailable
When a net.Server is configured with a `blockList`, the peer address is
looked up with getpeername() and checked before the connection is
accepted. If the peer address cannot be obtained (for example, the
connection was reset before getpeername(), causing
uv_tcp_getpeername() to return ENOTCONN), the access-control check was
silently skipped and the connection proceeded, allowing a blocked peer
to reach the application's 'connection' handler (fail open).
Fail closed: when a BlockList is configured but the peer address cannot
be determined, close the connection instead of bypassing the check. A
connection whose peer address cannot be obtained cannot be proven to be
allowed, so it must be refused.
Ref: https://github.com/nodejs/node/issues/66422
Ref: https://github.com/libuv/libuv/pull/5337
Signed-off-by: Matteo Collina <hello@matteocollina.com>
Assisted-by: pi
PR-URL: https://github.com/nodejs/node/pull/66640
Refs: https://github.com/nodejs/node/issues/66422
Refs: https://github.com/libuv/libuv/pull/5337
Reviewed-By: Tim Perry <pimterry@gmail.com>
diff --git a/lib/net.js b/lib/net.js
index 90b6ec9983f..5d20ea3ff45 100644
--- a/lib/net.js
+++ b/lib/net.js
@@ -2935,7 +2935,10 @@ function onconnection(err, clientHandle) {
const remoteInfo = { __proto__: null };
clientHandle.getpeername(remoteInfo);
const addressType = isIP(remoteInfo.address);
- if (addressType && self.blockList.check(remoteInfo.address, `ipv${addressType}`)) {
+ // Fail closed: if a BlockList is configured but the peer address cannot
+ // be obtained (e.g. the connection was reset before getpeername()),
+ // refuse the connection instead of silently bypassing the access control.
+ if (!addressType || self.blockList.check(remoteInfo.address, `ipv${addressType}`)) {
clientHandle.close();
return;
}
diff --git a/test/parallel/test-net-server-blocklist-fail-closed.js b/test/parallel/test-net-server-blocklist-fail-closed.js
new file mode 100644
index 00000000000..cb2ce18bde2
--- /dev/null
+++ b/test/parallel/test-net-server-blocklist-fail-closed.js
@@ -0,0 +1,33 @@
+'use strict';
+const common = require('../common');
+const net = require('net');
+
+const blockList = new net.BlockList();
+blockList.addCIDR('0.0.0.0/0');
+blockList.addCIDR('::/0');
+
+// A connection whose peer address cannot be determined (e.g. it was reset
+// before getpeername()) must be rejected when a BlockList is configured,
+// rather than being delivered to the application (fail closed).
+const server = net.createServer({ blockList }, common.mustNotCall());
+
+server.listen(0, common.mustCall(() => {
+ const socket = net.connect(server.address().port);
+ socket.on('error', () => {});
+}));
+
+const onconnection = server._handle.onconnection;
+server._handle.onconnection = common.mustCall((err, clientHandle) => {
+ const close = clientHandle.close;
+ // Simulate the reset-before-getpeername() condition: onconnection() is
+ // unable to obtain a valid peer address from the accepted connection.
+ clientHandle.getpeername = function(remoteInfo) {
+ remoteInfo.address = undefined;
+ };
+ clientHandle.close = common.mustCall(() => {
+ clientHandle.close = close;
+ close.call(clientHandle);
+ server.close();
+ });
+ onconnection.call(server._handle, err, clientHandle);
+});