-
Notifications
You must be signed in to change notification settings - Fork 30.5k
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 server message.url does not follow the whatwg url standard and does not evaluate ../ #51311
Comments
Can you provide a repro that does not involve downloading code from the internet, specifying what is the expected behavior and what you see instead? node/.github/ISSUE_TEMPLATE/1-bug-report.yml Lines 31 to 34 in 7981e2e
|
Hi @aduh95 import http from 'http';
http.createServer((request, response) => {
let targetUrl = new URL(`https://abc.com${request.url}`);
console.log(`incoming url: ${request.url}`);
console.log(`target url: ${targetUrl}`);
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
}).listen(3000); When calling the serer with: curl --path-as-is "localhost:3000/abc/../foobar" The output is
So the incoming url does not follow the whatwg standard as dot-segments are not removed. As a solution I could image to add an option to http.createServer that the message.url is parsed with the URL class. if(parseIncomingUrlwithWhatWg) {
const newUrl = (new URL(`htp://localhost${request.url}`));
request.url = newUrl.pathname + newUrl.search;
} Please also check out the WhatWg issue discussion |
cc @anonrig |
I think that changing the behavior would break the ecosystem so the only possibility would be in passing an option to |
We discussed this a bit today on the web server frameworks team. Here is a recap:
So for me, I would say that maybe the current options on the table for this are worse than the unexpected behavior and that we should work hard toward the new http api's being proposed instead. |
Thanks @wesleytodd for the recap and linking of the web-server-frameworks issue, good to know that it was even discussed there before. |
I did see that and read through the comments, I agree they gave different input but also I agree mostly with what was said over there. Honestly thinking about it maybe this comment should have been on that PR to keep the conversation together, this was just the link shared in the meeting.
Yeah this is, IMO, a valid goal. But I think different frameworks would have different targets, for example Fastify highly values performance so might decide not to use the parsed URL. On the other hand, Express might decide to use the URL instance as performance is a secondary concern compared to user expectations around web platform support. I say this because ideally I think Node core should offer both in easily consumed ways.
I mean that is some folks biggest concern, it is not mine (as I said above).
That is an open group, we would love to have you in those issues and helping us drive the decisison making on this topic. Feel free to hop in there! |
Version
18.17.1
Platform
All
Subsystem
No response
What steps will reproduce the bug?
I would like to share with you a very common scenario:
Express and fastify route matching is done on the incoming message url, which is not whatwg compliant url, see also discussion here This scenario can lead to path traversal vulnerabilities as the whatwg URL class will evaluate ../ and ./ but the server has matched on another path.
This situation is not good at all, because the developer need to know about the different parsing logic. I created this issue at Nodejs as the root cause of this the url property of the incoming message. As you can see in the linked property the fastify maintainer says that
Having different url representations in one framework/language is not good at all.
Example application
I have prepared a sample application using fastify:
https://github.com/stefanbeigel/whatwg-fastify-path-traversal/blob/main/index.mjs
Call the app with
curl --path-as-is localhost:3000/abc/../foobar
How often does it reproduce? Is there a required condition?
What is the expected behavior? Why is that the expected behavior?
OR
What do you see instead?
Additional information
Fastify: Different URL parsing between fastify and URL whatwg standard
WhatWG: URL path shortening for ../ creates problem with other URL parsers that do not follow the whatwg standard
Discussion: http(s) server why is request.url actually not an url, but a pathname. And why is parsing it now so hard?
The text was updated successfully, but these errors were encountered: