Skip to content

Commit 1e4187f

Browse files
rexagodmcollina
authored andcommitted
http2: add invalidheaders test
Refs: #29829 PR-URL: #33161 Reviewed-By: Robert Nagy <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]> Reviewed-By: Denys Otrishko <[email protected]>
1 parent ee7f0e3 commit 1e4187f

File tree

4 files changed

+84
-9
lines changed

4 files changed

+84
-9
lines changed

lib/internal/http2/compat.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ let statusConnectionHeaderWarned = false;
7373
// close as possible to the current require('http') API
7474

7575
const assertValidHeader = hideStackFrames((name, value) => {
76-
if (name === '' || typeof name !== 'string') {
76+
if (name === '' || typeof name !== 'string' || name.indexOf(' ') >= 0) {
7777
throw new ERR_INVALID_HTTP_TOKEN('Header name', name);
7878
}
7979
if (isPseudoHeader(name)) {

lib/internal/http2/util.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ const {
1818
ERR_HTTP2_INVALID_CONNECTION_HEADERS,
1919
ERR_HTTP2_INVALID_PSEUDOHEADER,
2020
ERR_HTTP2_INVALID_SETTING_VALUE,
21-
ERR_INVALID_ARG_TYPE
21+
ERR_INVALID_ARG_TYPE,
22+
ERR_INVALID_HTTP_TOKEN
2223
},
2324
addCodeToName,
2425
hideStackFrames
@@ -490,6 +491,9 @@ function mapToHeaders(map,
490491
count++;
491492
continue;
492493
}
494+
if (key.indexOf(' ') >= 0) {
495+
throw new ERR_INVALID_HTTP_TOKEN('Header name', key);
496+
}
493497
if (isIllegalConnectionSpecificHeader(key, value)) {
494498
throw new ERR_HTTP2_INVALID_CONNECTION_HEADERS(key);
495499
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
'use strict';
2+
const common = require('../common');
3+
if (!common.hasCrypto) { common.skip('missing crypto'); }
4+
5+
// Check for:
6+
// Spaced headers
7+
// Psuedo headers
8+
// Capitalized headers
9+
10+
const http2 = require('http2');
11+
const { throws, strictEqual } = require('assert');
12+
13+
const server = http2.createServer(common.mustCall((req, res) => {
14+
throws(() => {
15+
res.setHeader(':path', '/');
16+
}, {
17+
code: 'ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED'
18+
});
19+
throws(() => {
20+
res.setHeader('t est', 123);
21+
}, {
22+
code: 'ERR_INVALID_HTTP_TOKEN'
23+
});
24+
res.setHeader('TEST', 123);
25+
res.setHeader('test_', 123);
26+
res.setHeader(' test', 123);
27+
res.end();
28+
}));
29+
30+
server.listen(0, common.mustCall(() => {
31+
const session1 = http2.connect(`http://localhost:${server.address().port}`);
32+
session1.request({ 'test_': 123, 'TEST': 123 })
33+
.on('end', common.mustCall(() => {
34+
session1.close();
35+
server.close();
36+
}));
37+
38+
const session2 = http2.connect(`http://localhost:${server.address().port}`);
39+
session2.on('error', common.mustCall((e) => {
40+
strictEqual(e.code, 'ERR_INVALID_HTTP_TOKEN');
41+
}));
42+
throws(() => {
43+
session2.request({ 't est': 123 });
44+
}, {
45+
code: 'ERR_INVALID_HTTP_TOKEN'
46+
});
47+
48+
const session3 = http2.connect(`http://localhost:${server.address().port}`);
49+
session3.on('error', common.mustCall((e) => {
50+
strictEqual(e.code, 'ERR_INVALID_HTTP_TOKEN');
51+
}));
52+
throws(() => {
53+
session3.request({ ' test': 123 });
54+
}, {
55+
code: 'ERR_INVALID_HTTP_TOKEN'
56+
});
57+
58+
const session4 = http2.connect(`http://localhost:${server.address().port}`);
59+
throws(() => {
60+
session4.request({ ':test': 123 });
61+
}, {
62+
code: 'ERR_HTTP2_INVALID_PSEUDOHEADER'
63+
});
64+
session4.close();
65+
}));

test/parallel/test-http2-invalidheaderfields-client.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ const server1 = http2.createServer();
99
server1.listen(0, common.mustCall(() => {
1010
const session = http2.connect(`http://localhost:${server1.address().port}`);
1111
// Check for req headers
12-
session.request({ 'no underscore': 123 });
12+
assert.throws(() => {
13+
session.request({ 'no underscore': 123 });
14+
}, {
15+
code: 'ERR_INVALID_HTTP_TOKEN'
16+
});
1317
session.on('error', common.mustCall((e) => {
1418
assert.strictEqual(e.code, 'ERR_INVALID_HTTP_TOKEN');
1519
server1.close();
@@ -18,15 +22,18 @@ server1.listen(0, common.mustCall(() => {
1822

1923
const server2 = http2.createServer(common.mustCall((req, res) => {
2024
// check for setHeader
21-
res.setHeader('x y z', 123);
25+
assert.throws(() => {
26+
res.setHeader('x y z', 123);
27+
}, {
28+
code: 'ERR_INVALID_HTTP_TOKEN'
29+
});
2230
res.end();
2331
}));
2432

2533
server2.listen(0, common.mustCall(() => {
2634
const session = http2.connect(`http://localhost:${server2.address().port}`);
2735
const req = session.request();
28-
req.on('error', common.mustCall((e) => {
29-
assert.strictEqual(e.code, 'ERR_HTTP2_STREAM_ERROR');
36+
req.on('end', common.mustCall(() => {
3037
session.close();
3138
server2.close();
3239
}));
@@ -39,16 +46,15 @@ const server3 = http2.createServer(common.mustCall((req, res) => {
3946
'an invalid header': 123
4047
});
4148
}), {
42-
code: 'ERR_HTTP2_INVALID_STREAM'
49+
code: 'ERR_INVALID_HTTP_TOKEN'
4350
});
4451
res.end();
4552
}));
4653

4754
server3.listen(0, common.mustCall(() => {
4855
const session = http2.connect(`http://localhost:${server3.address().port}`);
4956
const req = session.request();
50-
req.on('error', common.mustCall((e) => {
51-
assert.strictEqual(e.code, 'ERR_HTTP2_STREAM_ERROR');
57+
req.on('end', common.mustCall(() => {
5258
server3.close();
5359
session.close();
5460
}));

0 commit comments

Comments
 (0)