Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
The X-Forwarded-Host HTTP header is always trusted and is used in url_for #29893
This has been reported twice on the rails HackerOne program, and the recommendation (from Jeremy) was to open a GitHub issue:
Steps to Reproduce
We're going to simulate a host header attack on a sample application. The sample application is a vanilla rails 5.1.2 application with a home page and one route added,
User is redirected to the home page:
User is redirected to the home page on evil.com:
(You can also verify the HTTP Location header for the redirect is set to
Rails version: 5.1.2
Ruby version: 2.4.0p0
As I understand it, rails uses the
This makes it very easy to create an open redirect in a rails application, in addition to creating many opportunities for reflection of URLs controlled by an attacker, since it affects all of rails's URL helpers through
To exploit it, the attacker needs to be able to inject the
There is at least one public bug report on HackerOne that demonstrates an attack vector, https://hackerone.com/reports/487.
It seems that GitLab tried to patch this problem in https://gitlab.com/gitlab-org/gitlab-ce/issues/17877 by removing the header in their NGINX layer. However, this caused a number of problems, and they had to remove the patch. According to the issue, they are going to try again with a whitelist of hosts.
This list of best practices https://github.com/ankane/secure_rails says that you should set
to avoid host injection, but when I tested it,
Express.js has a
If the header is not required, removing it appears to solve the problem. One way to do this is with a small piece of Rack middleware in
(Edit: This gem also implements the same approach: https://github.com/pusher/rack-headers_filter .)
This is the approach I'm trialling on my app, and so far it works OK.
Jeremy on HackerOne suggested:
I'm not at this point what the best approach is, so I've opted to open an issue for discussion.
I hope that's all clear. Let me know if you have any questions.
referenced this issue
Jul 22, 2017
Looked into it a bit more and my comment above isn't necessary (as redirects won't be cached), so I don't think redirects are an actual issue.
As far as I can tell, the mitigation technique above does work (however, it's not enabled by default).
Without it, you can end up with cache poisoning (as you mention @ouabing). The same thing can be accomplished with the
Thanks, everyone for your comments.
@ankane Thanks for your input. You are right about
For ease of reference, I've created a new heroku app, https://forwarded-host-demo-default.herokuapp.com/, that is running the code from the default-host branch (link to diff) of the demo app, which contains the
It's running the same commit,
When I go through the steps above to capture a request for
the response is still
In ankane/secure_rails#4, you also suggested that we try to render
<!DOCTYPE html> ... <pre> HTTP_X_FORWARDED_HOST = evil.com request.host = evil.com root_url = https://forwarded-host-demo.herokuapp.com/ </pre> <a href="/welcome/foo">redirect back to home page</a> ...
If I make the same request to the app without the
<!DOCTYPE html> ... <pre> HTTP_X_FORWARDED_HOST = evil.com request.host = evil.com root_url = http://evil.com/ </pre> <a href="/welcome/foo">redirect back to home page</a> ...
So, to sum up, I think this shows that:
Finally, I'd also note that the other workaround I suggested, which was to strip the
I'll also edit my comment above to make note of these points. Thanks again!
This issue has been automatically marked as stale because it has not been commented on for at least three months.
added a commit
Feb 5, 2018
Shouldn't this have a CVE number assigned to the Rails framework? If the Rails framework by default trusts the attacker for key functions, and that is not clearly documented on every function (e.g., "do not use"), then it seems like this deserves to be tracked as a vulnerability.
referenced this issue
Jul 8, 2018
I'm surprised that this is still an issue, that it still doesn't have a CVE, and that this assumption (that Rails can use client-supplied
We've found that defining a whitelist of valid hosts works best, by blocking malicious clients setting either
Include this in your ApplicationController:
You might find the following paper interesting - in it I explain in depth how the X-Forwarded-Host header can be used to exploit numerous real systems: https://portswigger.net/blog/practical-web-cache-poisoning
Zend, Symfony and Drupal had very a similar issue, and resolved it with a coordinated security release. As such I'm a little surprised to find this has been languishing in a public issue tracker.