-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
http: create an option for setting a maximum size for uri parsing #26553
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
45fa652
3218828
197d264
e7ade8b
78dfcf7
710e830
38307dc
93e384a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
The http server wasn't able to tell exactly what caused an HPE_HEADER_OVERFLOW, meaning it would yield a 431 error even if what caused it was the request URI being too long. This adds a limit to the URI sizes through a new option called max-http-uri-size, which will be checked against the actual URIs after on_url callback at the node_http_parser_impl file. Fixes: #26296 Refs: expressjs/express#3898
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -1959,6 +1959,17 @@ added: v11.6.0 | |||||
| Read-only property specifying the maximum allowed size of HTTP headers in bytes. | ||||||
| Defaults to 8KB. Configurable using the [`--max-http-header-size`][] CLI option. | ||||||
|
|
||||||
| ## http.maxUriSize | ||||||
| <!-- YAML | ||||||
| added: v12.0.0 | ||||||
| --> | ||||||
|
|
||||||
| * {number} | ||||||
|
|
||||||
| Read-only property specifying the maximum allowed size of HTTP request uri | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| in bytes. Defaults to 7KB. Configurable using the | ||||||
| [`--max-http-uri-size`][] CLI option. | ||||||
|
BridgeAR marked this conversation as resolved.
Outdated
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing bottom references. Will this option be documented later? |
||||||
|
|
||||||
| ## http.request(options[, callback]) | ||||||
| ## http.request(url[, options][, callback]) | ||||||
| <!-- YAML | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -426,6 +426,10 @@ PerProcessOptionsParser::PerProcessOptionsParser( | |
| "set the maximum size of HTTP headers (default: 8KB)", | ||
| &PerProcessOptions::max_http_header_size, | ||
| kAllowedInEnvironment); | ||
| AddOption("--max-http-uri-size", | ||
| "set the maximum size of HTTP request uri (default: 7KB)", | ||
| &PerProcessOptions::max_http_uri_size, | ||
| kAllowedInEnvironment); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fwiw, this should not be a per-process but rather a per-Environment option. |
||
| AddOption("--v8-pool-size", | ||
| "set V8's thread pool size", | ||
| &PerProcessOptions::v8_thread_pool_size, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| 'use strict'; | ||
| const assert = require('assert'); | ||
| const { createServer, maxUriSize } = require('http'); | ||
| const { createConnection } = require('net'); | ||
| const { expectsError, mustCall } = require('../common'); | ||
|
BridgeAR marked this conversation as resolved.
Outdated
|
||
|
|
||
| const CRLF = '\r\n'; | ||
| const REQUEST_METHOD_AND_SPACE = 'GET '; | ||
| const DUMMY_URI = '/' + 'a'.repeat( | ||
| maxUriSize | ||
| ); // the slash makes it just 1 byte too long | ||
|
BridgeAR marked this conversation as resolved.
Outdated
|
||
|
|
||
| const PAYLOAD = REQUEST_METHOD_AND_SPACE + DUMMY_URI + CRLF; | ||
|
|
||
| const server = createServer(); | ||
|
|
||
| server.on('connection', mustCall((socket) => { | ||
| socket.on('error', expectsError({ | ||
| type: Error, | ||
| message: 'Parse Error', | ||
| code: 'HPE_URI_OVERFLOW', | ||
| bytesParsed: REQUEST_METHOD_AND_SPACE.length + DUMMY_URI.length, | ||
| rawPacket: Buffer.from(PAYLOAD) | ||
| })); | ||
| })); | ||
|
|
||
| server.listen(0, mustCall(() => { | ||
| const c = createConnection(server.address().port); | ||
| let received = ''; | ||
|
|
||
| c.on('connect', mustCall(() => { | ||
| c.write(PAYLOAD); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is highly possible that the payload comes out of the other side of the socket as a single Buffer. Can you please add a test where the URL is split into two or more chunks? |
||
| })); | ||
| c.on('data', mustCall((data) => { | ||
| received += data.toString(); | ||
| })); | ||
| c.on('end', mustCall(() => { | ||
| assert.strictEqual( | ||
| received, | ||
| 'HTTP/1.1 414 URI Too Long\r\n' + | ||
| 'Connection: close\r\n\r\n' | ||
| ); | ||
| c.end(); | ||
| })); | ||
| c.on('close', mustCall(() => server.close())); | ||
| })); | ||
Uh oh!
There was an error while loading. Please reload this page.