| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent aee2a18 commit dafdc0a
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -53,6 +53,8 @@ const { | |||
| 53 | 53 | kUniqueHeaders, | |
| 54 | 54 | parseUniqueHeadersOption, | |
| 55 | 55 | OutgoingMessage, | |
| 56 | + validateHeaderName, | ||
| 57 | + validateHeaderValue, | ||
| 56 | 58 | } = require('_http_outgoing'); | |
| 57 | 59 | const { | |
| 58 | 60 | kOutHeaders, | |
@@ -331,13 +333,20 @@ ServerResponse.prototype.writeEarlyHints = function writeEarlyHints(hints, cb) { | |||
| 331 | 333 | return; | |
| 332 | 334 | } | |
| 333 | 335 | ||
| 336 | + if (checkInvalidHeaderChar(link)) { | ||
| 337 | + throw new ERR_INVALID_CHAR('header content', 'Link'); | ||
| 338 | + } | ||
| 339 | + | ||
| 334 | 340 | head += 'Link: ' + link + '\r\n'; | |
| 335 | 341 | ||
| 336 | 342 | const keys = ObjectKeys(hints); | |
| 337 | 343 | for (let i = 0; i < keys.length; i++) { | |
| 338 | 344 | const key = keys[i]; | |
| 339 | 345 | if (key !== 'link') { | |
| 340 | - head += key + ': ' + hints[key] + '\r\n'; | ||
| 346 | + validateHeaderName(key); | ||
| 347 | + const value = hints[key]; | ||
| 348 | + validateHeaderValue(key, value); | ||
| 349 | + head += key + ': ' + value + '\r\n'; | ||
| 341 | 350 | } | |
| 342 | 351 | } | |
| 343 | 352 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -509,7 +509,7 @@ function validateUnion(value, name, union) { | |||
| 509 | 509 | (not necessarily a valid URI reference) followed by zero or more | |
| 510 | 510 | link-params separated by semicolons. | |
| 511 | 511 | */ | |
| 512 | - const linkValueRegExp = /^(?:<[^>]*>)(?:\s*;\s*[^;"\s]+(?:=(")?[^;"\s]*\1)?)*$/; | ||
| 512 | + const linkValueRegExp = /^(?:<[^>\r\n]*>)(?:\s*;\s*[^;"\s]+(?:=(")?[^;"\s]*\1)?)*$/; | ||
| 513 | 513 | ||
| 514 | 514 | /** | |
| 515 | 515 | * @param {any} value | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -47,3 +47,44 @@ const testResBody = 'response content\n'; | |||
| 47 | 47 | req.on('information', common.mustNotCall()); | |
| 48 | 48 | })); | |
| 49 | 49 | } | |
| 50 | + | ||
| 51 | + { | ||
| 52 | + const server = http.createServer(common.mustCall((req, res) => { | ||
| 53 | + debug('Server sending early hints with CRLF injection...'); | ||
| 54 | + | ||
| 55 | + assert.throws(() => { | ||
| 56 | + res.writeEarlyHints({ | ||
| 57 | + 'link': '</styles.css>; rel=preload; as=style', | ||
| 58 | + 'X-Custom': 'valid\r\nSet-Cookie: session=evil', | ||
| 59 | + }); | ||
| 60 | + }, (err) => err.code === 'ERR_INVALID_CHAR'); | ||
| 61 | + | ||
| 62 | + assert.throws(() => { | ||
| 63 | + res.writeEarlyHints({ | ||
| 64 | + 'link': '</styles.css>; rel=preload; as=style', | ||
| 65 | + 'X-Custom\r\nSet-Cookie: session=evil': 'value', | ||
| 66 | + }); | ||
| 67 | + }, (err) => err.code === 'ERR_INVALID_HTTP_TOKEN'); | ||
| 68 | + | ||
| 69 | + assert.throws(() => { | ||
| 70 | + res.writeEarlyHints({ | ||
| 71 | + link: '</styles.css\r\nSet-Cookie: session=evil>; rel=preload; as=style', | ||
| 72 | + }); | ||
| 73 | + }, (err) => err.code === 'ERR_INVALID_ARG_VALUE'); | ||
| 74 | + | ||
| 75 | + debug('Server sending full response...'); | ||
| 76 | + res.end(testResBody); | ||
| 77 | + server.close(); | ||
| 78 | + })); | ||
| 79 | + | ||
| 80 | + server.listen(0, common.mustCall(() => { | ||
| 81 | + const req = http.request({ | ||
| 82 | + port: server.address().port, path: '/' | ||
| 83 | + }); | ||
| 84 | + | ||
| 85 | + req.end(); | ||
| 86 | + debug('Client sending request...'); | ||
| 87 | + | ||
| 88 | + req.on('information', common.mustNotCall()); | ||
| 89 | + })); | ||
| 90 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments