node/test/parallel/test-http-headers-distinct-proto.js
Matteo Collina a2fe9fd81a
http: use null prototype for headersDistinct/trailersDistinct
Use { __proto__: null } instead of {} when initializing the
headersDistinct and trailersDistinct destination objects.

A plain {} inherits from Object.prototype, so when a __proto__
header is received, dest["__proto__"] resolves to Object.prototype
(truthy), causing _addHeaderLineDistinct to call .push() on it,
which throws an uncaught TypeError and crashes the process.

Ref: https://hackerone.com/reports/3560402
PR-URL: https://github.com/nodejs-private/node-private/pull/821
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
CVE-ID: CVE-2026-21710
2026-03-22 16:28:36 +01:00

36 lines
964 B
JavaScript

'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');
const net = require('net');
// Regression test: sending a __proto__ header must not crash the server
// when accessing req.headersDistinct or req.trailersDistinct.
const server = http.createServer(common.mustCall((req, res) => {
const headers = req.headersDistinct;
assert.strictEqual(Object.getPrototypeOf(headers), null);
assert.deepStrictEqual(Object.getOwnPropertyDescriptor(headers, '__proto__').value, ['test']);
res.end();
}));
server.listen(0, common.mustCall(() => {
const port = server.address().port;
const client = net.connect(port, common.mustCall(() => {
client.write(
'GET / HTTP/1.1\r\n' +
'Host: localhost\r\n' +
'__proto__: test\r\n' +
'Connection: close\r\n' +
'\r\n',
);
}));
client.on('end', common.mustCall(() => {
server.close();
}));
client.resume();
}));