Skip to content
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

http: disallow sending obviously invalid status codes #6291

Closed
wants to merge 1 commit into from

Conversation

mscdex
Copy link
Contributor

@mscdex mscdex commented Apr 20, 2016

Checklist
  • tests and code linting passes
  • a test and/or benchmark is included
  • the commit message follows commit guidelines
Affected core subsystem(s)
  • http
Description of change

Disallows sending of invalid status codes.

@mscdex mscdex added the http Issues or PRs related to the http subsystem. label Apr 20, 2016
@mscdex
Copy link
Contributor Author

mscdex commented Apr 20, 2016

/cc @nodejs/http

CI: https://ci.nodejs.org/job/node-test-pull-request/2333/

@mscdex mscdex force-pushed the http-disallow-bad-statuscode branch from 8406b4d to 3e01bad Compare April 20, 2016 00:58
@jasnell
Copy link
Member

jasnell commented Apr 20, 2016

This should likely also catch anything less than 100 and greater than 599

@mscdex
Copy link
Contributor Author

mscdex commented Apr 20, 2016

@jasnell True, but I was aiming to be as backwards compatible as possible with this. Who knows if anyone out there is using custom/unofficial status codes.

@mscdex
Copy link
Contributor Author

mscdex commented Apr 20, 2016

Tagging this for possible backporting to v4.x, feel free to remove if you think it shouldn't be. I see this as a bug fix though.

@jasnell
Copy link
Member

jasnell commented Apr 20, 2016

Anyone using anything less than 100 likely has other problems to deal with
as there are parsers that will die completely if there aren't three digits.
It's conceivable that someone is using numbers higher than 599. Perhaps
catch anything that's not 3-digits? 100 <= n <= 999?
On Apr 19, 2016 6:02 PM, "Brian White" notifications@github.com wrote:

@jasnell https://github.com/jasnell True, but I was aiming to be as
backwards compatible as possible with this. Who knows if anyone out there
is using custom/unofficial status codes.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#6291 (comment)

@mscdex
Copy link
Contributor Author

mscdex commented Apr 20, 2016

If we're going to validate the numerical value, I would lean more towards a 3-digit check.

What do other @nodejs/collaborators think?

@indutny
Copy link
Member

indutny commented Apr 20, 2016

What's the reason for introduction of this patch at this point? Is there any open issue about it?

@mscdex
Copy link
Contributor Author

mscdex commented Apr 20, 2016

@indutny
Copy link
Member

indutny commented Apr 20, 2016

Alright, thank you!

@@ -187,6 +187,10 @@ ServerResponse.prototype.writeHead = function(statusCode, reason, obj) {
headers = obj;
}

const statusCode_ = +statusCode;
if (statusCode_ < 0 || !isFinite(statusCode_))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not Number.isInteger?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Number.isInteger() would return false for strings of valid numbers.

@mscdex mscdex force-pushed the http-disallow-bad-statuscode branch from 3e01bad to f9063c7 Compare April 20, 2016 02:35
@mscdex
Copy link
Contributor Author

mscdex commented Apr 20, 2016

Ok, I've modified it to check the number of digits now.

CI: https://ci.nodejs.org/job/node-test-pull-request/2335/
New CI: https://ci.nodejs.org/job/node-test-pull-request/2336/

@mscdex mscdex force-pushed the http-disallow-bad-statuscode branch from f9063c7 to dcda312 Compare April 20, 2016 02:42
@jasnell
Copy link
Member

jasnell commented Apr 20, 2016

LGTM if CI is green

@thefourtheye
Copy link
Contributor

I am okay with this. LGTM. semver major?

@mscdex
Copy link
Contributor Author

mscdex commented Apr 20, 2016

@thefourtheye Possibly, but it is a bug fix shrug.

@@ -187,6 +187,10 @@ ServerResponse.prototype.writeHead = function(statusCode, reason, obj) {
headers = obj;
}

statusCode |= 0;
if (statusCode < 100 || statusCode > 999)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I am not sure if this really matters but the expected port range is just 100-599 http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml

Copy link
Contributor Author

@mscdex mscdex Apr 20, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, @jasnell mentioned this already. However I think it might be better to be a bit more lenient in case of custom/unofficial/whatever status codes out in the wild.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry. I didn't read the comments completely.

@jasnell
Copy link
Member

jasnell commented Apr 20, 2016

I think if we keep it at any three digit code we can easily justify landing
it as a patch.
On Apr 19, 2016 7:47 PM, "Brian White" notifications@github.com wrote:

@thefourtheye https://github.com/thefourtheye Probably, but it is a
bug fix shrug.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#6291 (comment)

@ChALkeR
Copy link
Member

ChALkeR commented Apr 20, 2016

LGTM

break;
case 5:
assert.throws(common.mustCall(() => {
res.writeHead(1000);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps also have a case for a non-numeric string?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 ... null, 'this is not invalid, [], true, etc could all be included in the tests here, just to be overly careful ;-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested tests added.

@indutny
Copy link
Member

indutny commented Apr 20, 2016

LGTM

@benjamingr
Copy link
Member

LGTM, I like this change.

@@ -187,6 +187,10 @@ ServerResponse.prototype.writeHead = function(statusCode, reason, obj) {
headers = obj;
}

statusCode |= 0;
if (statusCode < 100 || statusCode > 999)
throw new Error(`Invalid status code: ${statusCode}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a RangeError?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should passing 'NotAStatusCode' cause a RangeError?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChALkeR It's debatable, but since statusCode is ultimately coerced to an integer value (e.g. 0 for non-numeric values) I thought maybe RangeError would fit better since 0 < 100. shrug

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that works for me =).

@cjihrig
Copy link
Contributor

cjihrig commented Apr 20, 2016

LGTM with a comment.

@mscdex mscdex force-pushed the http-disallow-bad-statuscode branch from dcda312 to ec50170 Compare April 20, 2016 13:51
@jasnell
Copy link
Member

jasnell commented Apr 20, 2016

Just one additional minor comment on the tests. Otherwise still LGTM

@mscdex mscdex force-pushed the http-disallow-bad-statuscode branch from ec50170 to 35b4f99 Compare April 20, 2016 15:37
@jasnell jasnell closed this Apr 20, 2016
MylesBorins pushed a commit that referenced this pull request Apr 20, 2016
PR-URL: #6291
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
@mscdex mscdex deleted the http-disallow-bad-statuscode branch April 21, 2016 00:33
This was referenced Apr 21, 2016
MylesBorins pushed a commit that referenced this pull request Apr 21, 2016
PR-URL: #6291
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
joelostrowski pushed a commit to joelostrowski/node that referenced this pull request Apr 25, 2016
PR-URL: nodejs#6291
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
jasnell pushed a commit that referenced this pull request Apr 26, 2016
PR-URL: #6291
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
@MylesBorins
Copy link
Contributor

I'm adding this to v4.x-staging and to the v4.4.5 release candidate.

if anyone objects or if we see any weird regressions I will back it out

MylesBorins pushed a commit that referenced this pull request May 18, 2016
PR-URL: #6291
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 18, 2016
PR-URL: #6291
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 18, 2016
Notable changes:

* deps:
  * update npm to 2.15.5 (Rebecca Turner)
    #6663
  * update ESLint to 2.7.0 (silverwind)
    #6132

* http:
  * Invalid status codes can no longer be sent. Limited to 3 digit
    numbers between 100 - 999 (Brian White)
    #6291
@MylesBorins MylesBorins mentioned this pull request May 18, 2016
MylesBorins pushed a commit that referenced this pull request May 18, 2016
Notable changes:

* **buffer**:
  * Buffer no longer errors if you call lastIndexOf with a search term
    longer than the buffer (Anna Henningsen)
    #6511

* deps:
  * update npm to 2.15.5 (Rebecca Turner)
    #6663

* http:
  * Invalid status codes can no longer be sent. Limited to 3 digit
    numbers between 100 - 999 (Brian White)
    #6291
MylesBorins pushed a commit that referenced this pull request May 20, 2016
Notable changes:

* **buffer**:
  * Buffer no longer errors if you call lastIndexOf with a search term
    longer than the buffer (Anna Henningsen)
    #6511

* contextify:
  * Context objects are now properly garbage collected, this solves a
    problem some individuals were experiencing with extreme memory
    growth (Ali Ijaz Sheikh)
    #6871

* deps:
  * update npm to 2.15.5 (Rebecca Turner)
    #6663

* http:
  * Invalid status codes can no longer be sent. Limited to 3 digit
    numbers between 100 - 999 (Brian White)
    #6291
MylesBorins pushed a commit that referenced this pull request May 23, 2016
Notable changes:

* **buffer**:
  * Buffer no longer errors if you call lastIndexOf with a search term
    longer than the buffer (Anna Henningsen)
    #6511

* contextify:
  * Context objects are now properly garbage collected, this solves a
    problem some individuals were experiencing with extreme memory
    growth (Ali Ijaz Sheikh)
    #6871

* deps:
  * update npm to 2.15.5 (Rebecca Turner)
    #6663

* http:
  * Invalid status codes can no longer be sent. Limited to 3 digit
    numbers between 100 - 999 (Brian White)
    #6291
MylesBorins pushed a commit that referenced this pull request May 24, 2016
Notable changes:

* **buffer**:
  * Buffer no longer errors if you call lastIndexOf with a search term
    longer than the buffer (Anna Henningsen)
    #6511

* contextify:
  * Context objects are now properly garbage collected, this solves a
    problem some individuals were experiencing with extreme memory
    growth (Ali Ijaz Sheikh)
    #6871

* deps:
  * update npm to 2.15.5 (Rebecca Turner)
    #6663

* http:
  * Invalid status codes can no longer be sent. Limited to 3 digit
    numbers between 100 - 999 (Brian White)
    #6291
MylesBorins pushed a commit that referenced this pull request May 24, 2016
Notable changes:

* **buffer**:
  * Buffer no longer errors if you call lastIndexOf with a search term
    longer than the buffer (Anna Henningsen)
    #6511

* contextify:
  * Context objects are now properly garbage collected, this solves a
    problem some individuals were experiencing with extreme memory
    growth (Ali Ijaz Sheikh)
    #6871

* deps:
  * update npm to 2.15.5 (Rebecca Turner)
    #6663

* http:
  * Invalid status codes can no longer be sent. Limited to 3 digit
    numbers between 100 - 999 (Brian White)
    #6291
@rmg
Copy link
Contributor

rmg commented May 24, 2016

Code that would previously run and happily dish out invalid status codes will now die from unhandled exceptions. Isn't that sort of the definition of a breaking change? Upgrading from v4.4.4 to v4.4.5 shouldn't require people to modify their code.

@rmg
Copy link
Contributor

rmg commented May 24, 2016

It's too late now, and that I have the advantage of hindsight...

If this PR was 2 commits, with the first one adding the (semver-patch) statusCode |= 0 line and the second adding the (semver-major) strict range check, then we could have pulled in only part of the change for LTS.

@Fishrock123
Copy link
Contributor

I was also quite surprised to see this backported.

case 0:
assert.throws(common.mustCall(() => {
res.writeHead(-1);
}, /invalid status code/i));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The closing parenthesis for common.mustCall() is misplaced here and on the other lines. It should read:

}), /invalid status code/i);

With the current code, the RegExp is passed to mustCall as the expected paramater, and then silently replaced with 1 because it's non-numeric. Then the assert.throws call doesn't validate the error message and passes the test as long as any error is thrown.

I'll fix this along with my patch for #9027 unless you'd prefer to see it in a separate PR.

@aivus
Copy link

aivus commented Nov 17, 2016

Thank you, guys, we got broken app after patch-upgrade👏

FYI, http://semver.org/

PATCH version when you make backwards-compatible bug fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
http Issues or PRs related to the http subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.