1'use strict'; 2 3// Response splitting is no longer an issue with HTTP/2. The underlying 4// nghttp2 implementation automatically strips out the header values that 5// contain invalid characters. 6 7const common = require('../common'); 8if (!common.hasCrypto) 9 common.skip('missing crypto'); 10const assert = require('assert'); 11const http2 = require('http2'); 12 13// Response splitting example, credit: Amit Klein, Safebreach 14const str = '/welcome?lang=bar%c4%8d%c4%8aContentLength:%200%c4%8d%c4%8a%c' + 15 '4%8d%c4%8aHTTP/1.1%20200%20OK%c4%8d%c4%8aContentLength:%202' + 16 '0%c4%8d%c4%8aLastModified:%20Mon,%2027%20Oct%202003%2014:50:18' + 17 '%20GMT%c4%8d%c4%8aContentType:%20text/html%c4%8d%c4%8a%c4%8' + 18 'd%c4%8a%3chtml%3eGotcha!%3c/html%3e'; 19 20// Response splitting example, credit: Сковорода Никита Андреевич (@ChALkeR) 21const x = 'fooഊSet-Cookie: foo=barഊഊ<script>alert("Hi!")</script>'; 22const y = 'foo⠊Set-Cookie: foo=bar'; 23 24let remaining = 3; 25 26function makeUrl(headers) { 27 return `${headers[':scheme']}://${headers[':authority']}${headers[':path']}`; 28} 29 30const server = http2.createServer(); 31server.on('stream', common.mustCall((stream, headers) => { 32 33 const obj = Object.create(null); 34 switch (remaining--) { 35 case 3: { 36 const url = new URL(makeUrl(headers)); 37 obj[':status'] = 302; 38 obj.Location = `/foo?lang=${url.searchParams.get('lang')}`; 39 break; 40 } 41 case 2: 42 obj.foo = x; 43 break; 44 case 1: 45 obj.foo = y; 46 break; 47 } 48 stream.respond(obj); 49 stream.end(); 50}, 3)); 51 52server.listen(0, common.mustCall(() => { 53 const client = http2.connect(`http://localhost:${server.address().port}`); 54 55 function maybeClose() { 56 if (remaining === 0) { 57 server.close(); 58 client.close(); 59 } 60 } 61 62 function doTest(path, key, expected) { 63 const req = client.request({ ':path': path }); 64 req.on('response', common.mustCall((headers) => { 65 assert.strictEqual(headers.foo, undefined); 66 assert.strictEqual(headers.location, undefined); 67 })); 68 req.resume(); 69 req.on('end', common.mustCall()); 70 req.on('close', common.mustCall(maybeClose)); 71 } 72 73 doTest(str, 'location', str); 74 doTest('/', 'foo', x); 75 doTest('/', 'foo', y); 76 77})); 78