-
-
Notifications
You must be signed in to change notification settings - Fork 19.1k
added newline character check in url in response.redirect function #974
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
Conversation
if you're accepting user-input it should be filtered at that point. This issue would apply to any method setting a header field, even node's setHeader() itself, so if the user doesn't trust the input it should be sanitized or cause a client error response |
// Throw exception if url contains newline characters to avoid HTTP Response Splitting attack | ||
// https://www.owasp.org/index.php/HTTP_Response_Splitting | ||
if(url.indexOf('\n') !== -1) { | ||
throw 'redirect uri contains newline characters'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pointing this bad pattern, I fixed that.
https://github.com/alpercelik/express/commit/f8bff5765474e35b5d3d54c3e7a56c3bc94cfd10
I completely agree that user-input should be checked this doesn't imply that user-input is not required. I agree with you that this issue would apply to any method that may cause unintended header injection. But looking at the redirect method, my opinion is that url parameter itself is the user-input (from the API point of view), and url parameter should be a valid url that can be redirected safely. This method passes url parameter to headers as it is and newline will definitively cause input to be injected to headers. Example shown actually is a simple scenario which accepts the url parameter directly from request parameter. But considering applications that you have not accepted the url from "user" but may be coming from a database where it have passed user-input validations due to missing or insufficient controls in another entry-point, or being provided to your application as a return url. I added the check right after the url where it is mapped. Here again the question was trustfulness of final url, since it may also be constructed via app.redirect mappings. It may be constructed using some data that comes from model which has such injection and not escaped. In asp.net framework, redirect method of response class checks the url parameter if it contains any newline characters at first place.If it contains it throws exception and I followed the same approach. I am not php/ruby guy but as I researched it seems that;
I am not sure which behavior fits best, throwing error or sanitizing, but personally I think there should be a prevention in express framework. |
I'm -1 for throwing because then nearly every res.redirect() call would need a try/catch. If we were to solve it lower in the stack it should be even lower than res.redirect since that still leaves everything else open. In general it's best practice to filter the input so you know it's "safe" when used throughout but can I see how this would be a big headache like the fs module + nul bytes, so I'll definitely think about it but the lowest we could go in Express is |
I just started evaluating express and I liked it. I have not gone through the details express, so I just tried to fix for redirect case. I'll close my pull request and would be happy to see a general and a better solution applied. |
if you're taking it to node core you can show them something similar to: http.createServer(function(req, res){
var body = 'oh noes';
var userInput = 'foo\r\n'
+ 'Content-Length: ' + body.length + '\r\n'
+ '\r\n'
+ body;
res.setHeader('Location', userInput);
res.end();
}).listen(3000); I cant remember if the fs nul byte thing got in or not but this is pretty similar |
I had also fixed and pushed to my fork :) I was opening an issue with node and then received the notification :) I did it it at the same location but I also checked for null bytes. |
currently express framework do not check for newline characters
it is vulnerable to http splitting attack
example:
start the test server https://gist.github.com/1654555
browse http://localhost:3000/?foo=bar%0D%0ASet-Cookie%3Aname%3Dvalue
you will be re redirected to another page and cookie will be set