mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
Makes IncomingMessage.prototype.headers and trailers have a null prototype, matching the existing behavior of headersDistinct and trailersDistinct. Fixes prototype pollution concerns where headers like __proto__ could be interpreted as prototype manipulation. Refs: https://github.com/nodejs/node/issues/61771 PR-URL: https://github.com/nodejs/node/pull/62900 Reviewed-By: Jordan Harband <ljharb@gmail.com> Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day> Reviewed-By: Tim Perry <pimterry@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: René <contact.9a5d6388@renegade334.me.uk> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
107 lines
2.6 KiB
JavaScript
107 lines
2.6 KiB
JavaScript
'use strict';
|
|
|
|
const common = require('../common');
|
|
const assert = require('assert');
|
|
const http = require('http');
|
|
const net = require('net');
|
|
|
|
// Test 1: req.headers has a null prototype
|
|
{
|
|
const server = http.createServer(common.mustCall((req, res) => {
|
|
assert.strictEqual(Object.getPrototypeOf(req.headers), null);
|
|
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' +
|
|
'Connection: close\r\n' +
|
|
'\r\n',
|
|
);
|
|
}));
|
|
|
|
client.on('end', common.mustCall(() => {
|
|
server.close();
|
|
}));
|
|
|
|
client.resume();
|
|
}));
|
|
}
|
|
|
|
// Test 2: req.trailers has a null prototype
|
|
{
|
|
const server = http.createServer(common.mustCall((req, res) => {
|
|
req.on('end', common.mustCall(() => {
|
|
assert.strictEqual(Object.getPrototypeOf(req.trailers), null);
|
|
assert.strictEqual(req.trailers['x-client-trailer'], 'bar');
|
|
}));
|
|
res.setHeader('Transfer-Encoding', 'chunked');
|
|
res.setHeader('Trailer', 'X-Trailer');
|
|
res.write('Hello');
|
|
res.addTrailers({
|
|
'X-Trailer': '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' +
|
|
'Transfer-Encoding: chunked\r\n' +
|
|
'Trailer: X-Client-Trailer\r\n' +
|
|
'Connection: close\r\n' +
|
|
'\r\n' +
|
|
'0\r\n' +
|
|
'X-Client-Trailer: bar\r\n' +
|
|
'\r\n',
|
|
);
|
|
}));
|
|
|
|
client.on('data', () => {});
|
|
|
|
client.on('end', common.mustCall(() => {
|
|
server.close();
|
|
}));
|
|
}));
|
|
}
|
|
|
|
// Test 3: req.headers with __proto__ header (should not pollute prototype)
|
|
{
|
|
const server = http.createServer(common.mustCall((req, res) => {
|
|
assert.strictEqual(Object.getPrototypeOf(req.headers), null);
|
|
// The __proto__ header should be stored as a regular property
|
|
assert.strictEqual(
|
|
Object.getOwnPropertyDescriptor(req.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();
|
|
}));
|
|
}
|