node/test/parallel/test-http2-response-splitting.js
Jordan Harband 757c104147
tools: add prefer-proto rule
fixup: add support for `Object.create(null)`

fixup: extend to any 1-argument Object.create call

fixup: add tests
PR-URL: https://github.com/nodejs/node/pull/46083
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2023-01-10 05:38:36 +00:00

78 lines
2.2 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
// Response splitting is no longer an issue with HTTP/2. The underlying
// nghttp2 implementation automatically strips out the header values that
// contain invalid characters.
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const assert = require('assert');
const http2 = require('http2');
// Response splitting example, credit: Amit Klein, Safebreach
const str = '/welcome?lang=bar%c4%8d%c4%8aContent­Length:%200%c4%8d%c4%8a%c' +
'4%8d%c4%8aHTTP/1.1%20200%20OK%c4%8d%c4%8aContent­Length:%202' +
'0%c4%8d%c4%8aLast­Modified:%20Mon,%2027%20Oct%202003%2014:50:18' +
'%20GMT%c4%8d%c4%8aContent­Type:%20text/html%c4%8d%c4%8a%c4%8' +
'd%c4%8a%3chtml%3eGotcha!%3c/html%3e';
// Response splitting example, credit: Сковорода Никита Андреевич (@ChALkeR)
const x = 'fooഊSet-Cookie: foo=barഊഊ<script>alert("Hi!")</script>';
const y = 'foo⠊Set-Cookie: foo=bar';
let remaining = 3;
function makeUrl(headers) {
return `${headers[':scheme']}://${headers[':authority']}${headers[':path']}`;
}
const server = http2.createServer();
server.on('stream', common.mustCall((stream, headers) => {
const obj = { __proto__: null };
switch (remaining--) {
case 3: {
const url = new URL(makeUrl(headers));
obj[':status'] = 302;
obj.Location = `/foo?lang=${url.searchParams.get('lang')}`;
break;
}
case 2:
obj.foo = x;
break;
case 1:
obj.foo = y;
break;
}
stream.respond(obj);
stream.end();
}, 3));
server.listen(0, common.mustCall(() => {
const client = http2.connect(`http://localhost:${server.address().port}`);
function maybeClose() {
if (remaining === 0) {
server.close();
client.close();
}
}
function doTest(path, key, expected) {
const req = client.request({ ':path': path });
req.on('response', common.mustCall((headers) => {
assert.strictEqual(headers.foo, undefined);
assert.strictEqual(headers.location, undefined);
}));
req.resume();
req.on('end', common.mustCall());
req.on('close', common.mustCall(maybeClose));
}
doTest(str, 'location', str);
doTest('/', 'foo', x);
doTest('/', 'foo', y);
}));