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

The X-Forwarded-Host HTTP header is always trusted and is used in url_for #29893

Closed
jdleesmiller opened this issue Jul 22, 2017 · 21 comments
Closed

Comments

@jdleesmiller
Copy link

jdleesmiller commented Jul 22, 2017

Background

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, foo, to redirect back to the home page. The code is available here: https://github.com/jdleesmiller/forwarded_host_demo

  1. Visit http://forwarded-host-demo.herokuapp.com/ (it may need some time to boot up)

  2. Open the network tools in your browser (I used Chrome) and tick the option to preserve requests.

  3. Click the 'redirect back to home page' link. You are redirected to the home page.

  4. Copy the corresponding request for /foo as a cURL command from the browser's network tools (right click, Copy, Copy as cURL).

  5. To simulate a host header attack, paste the curl command into a terminal and add -H 'X-Forwarded-Host: evil.com'. For example, for one of my requests:

    curl 'http://forwarded-host-demo.herokuapp.com/welcome/foo' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Accept-Language: en-GB,en-US;q=0.8,en;q=0.6' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' -H 'Accept: text/html, application/xhtml+xml' -H 'Referer: http://forwarded-host-demo.herokuapp.com/' -H 'Cookie: _forwarded_host_session=RjRsTFduOUg5ZStSUCtlVWtYOWN6cVVsVHNzV1Y5aWNWUlZYVXYvcGZKMVhTSmI3Njg5cURiUFltaTE2cVh0STNreENLbmJLR1pNWlkwWDA0UmhNdERpZzEzOW53aWk2QndkdHhNWkp2L0l2bnFoNlpwdUdNekJUVnBmcHc2SUwwZzdCSDh5RTNFOTdCUTVFRkZoLzFRPT0tLWU1M1k4OVpNZ0lIL0UyUXp0SHN0Rnc9PQ%3D%3D--a85dd504e2416f8cbb387b7bb32184dd9e31337a' -H 'Connection: keep-alive' -H 'Turbolinks-Referrer: http://forwarded-host-demo.herokuapp.com/' -H 'X-Forwarded-Host: evil.com' --compressed
    

Expected Result

User is redirected to the home page:

<html><body>You are being <a href="http://forwarded-host-demo.herokuapp.com/">redirected</a>.</body></html>

Observed Result

User is redirected to the home page on evil.com:

<html><body>You are being <a href="http://evil.com/">redirected</a>.</body></html>

(You can also verify the HTTP Location header for the redirect is set to http://evil.com by passing -i to curl.)

System configuration

Rails version: 5.1.2

Ruby version: 2.4.0p0

Analysis

As I understand it, rails uses the X-Forwarded-Host HTTP header in preference to the Host HTTP header in ActionDispatch::Http::URL to compute request.host. request.host is in turn used in url_for.

Impact

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 url_for.

To exploit it, the attacker needs to be able to inject the X-Forwarded-Host header, which can be accomplished by cache poisoning.

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.

Whether the X-Forwarded-Host header is under the user's control does depend on the upstream proxy configuration. On heroku, the steps to reproduce above with my sample app show that it is under user control, so that accounts for a large number of rails applications.

Mitigation

This list of best practices https://github.com/ankane/secure_rails says that you should set

config.action_controller.default_url_options = {host: "www.yoursite.com"}
config.action_controller.asset_host = "www.yoursite.com"

to avoid host injection, but when I tested it, it had no effect (edit: it is a partial fix; see #29893 (comment)). (I tried it on this branch: https://github.com/jdleesmiller/forwarded_host_demo/tree/default-host .) I think the request.host takes precedence over the default setting, which is only used when operating without a request, for example in a background worker. (see #29893 (comment))

Express.js has a trust proxy setting that, among other things, determines whether the app will trust X-Forwarded-Host to set the hostname. I could not find any similar option for rails; rails has good handling of IP spoofing with X-Forwarded-For, but I cannot see any countermeasures against X-Forwarded-Host spoofing.

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 config/application.rb:

    class StripXForwardedHost
      def initialize(app)
        @app = app
      end

      def call(env)
        env.delete('HTTP_X_FORWARDED_HOST')
        @app.call(env)
      end
    end
    config.middleware.use StripXForwardedHost

(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:

Ideally, we'd validate the host header against an allow-list. This is the approach we take for Action Cable allowed origins.

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.

@ankane
Copy link

ankane commented Jul 27, 2017

I think a simple solution would be for redirect_to some_path to use the host from config.action_controller.default_url_options if it exists (of course, won't protect apps that don't have it set). redirect_to some_url does not have the same issue.

@ouabing
Copy link

ouabing commented Aug 2, 2017

I think the big problem is, this kind of response will be cached by rails if you enable page cache and use url_for in views.

@ankane
Copy link

ankane commented Aug 2, 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 Host header. What maybe makes the X-Forwarded-Host header different is some load balancers (like the ones Heroku runs) are configured to route based on the Host header, making it impossible for an evil host to make it to the Rails app.

@jdleesmiller
Copy link
Author

jdleesmiller commented Aug 2, 2017

Thanks, everyone for your comments.

@ankane Thanks for your input. You are right about root_url. However, the default_url_options workaround still does not seem to prevent attacker-controlled redirects.

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 default_url_options workaround.

It's running the same commit, 02590cd5, as the branch.

$ heroku releases -a forwarded-host-demo-default
=== forwarded-host-demo-default Releases - Current: v5
v5  Deploy 02590cd5                                                                                             -snip-  2017/08/02 19:36:38 +0100 (~ 38s ago)
...

When I go through the steps above to capture a request for /welcome/foo and curl it with the -H 'X-Forwarded-Host: evil.com' option:

$ curl 'https://forwarded-host-demo-default.herokuapp.com/welcome/foo' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-GB,en-US;q=0.8,en;q=0.6' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36' -H 'Accept: text/html, application/xhtml+xml' -H 'Referer: https://forwarded-host-demo-default.herokuapp.com/' -H 'Cookie: _forwarded_host_session=UDBEQXhHclAvY3phbmx1VWRiZWhKV3FMUU9HcmNwU291SHZyOW9xNlJZblAzSW1acE8xYW4zMlcyU2taMUEvcnRObW1BdkJJeEJsalovOWRrejNkOWE2ZWRVeDUzdVhsVUVzKzRnY1Jad1A3L0xnbHRvZ0dxRDZxMDZtZFlXcGx2VFJxQTZ0ekJNb3E4ZVBRSWovaHVnPT0tLWE3WVlTZEtvRjVXUnNNVDQ1MVhnd0E9PQ%3D%3D--a6835674c0bf2075c786df489bafd0b0191b4880' -H 'Connection: keep-alive' -H 'Turbolinks-Referrer: https://forwarded-host-demo-default.herokuapp.com/' --compressed -H 'X-Forwarded-Host: evil.com'

the response is still

<html><body>You are being <a href="https://evil.com/">redirected</a>.</body></html>

In ankane/secure_rails#4, you also suggested that we try to render root_url, which we can do by curling the root with the evil X-Forwarded-Host header. That does indeed render the default value (set to forwarded-host-demo.herokuapp.com on the branch) for root_url, even though request.host is evil.com:

$ curl 'https://forwarded-host-demo-default.herokuapp.com/' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-GB,en-US;q=0.8,en;q=0.6' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36' -H 'Accept: text/html, application/xhtml+xml' -H 'Referer: https://forwarded-host-demo-default.herokuapp.com/' -H 'Cookie: _forwarded_host_session=UDBEQXhHclAvY3phbmx1VWRiZWhKV3FMUU9HcmNwU291SHZyOW9xNlJZblAzSW1acE8xYW4zMlcyU2taMUEvcnRObW1BdkJJeEJsalovOWRrejNkOWE2ZWRVeDUzdVhsVUVzKzRnY1Jad1A3L0xnbHRvZ0dxRDZxMDZtZFlXcGx2VFJxQTZ0ekJNb3E4ZVBRSWovaHVnPT0tLWE3WVlTZEtvRjVXUnNNVDQ1MVhnd0E9PQ%3D%3D--a6835674c0bf2075c786df489bafd0b0191b4880' -H 'Connection: keep-alive' -H 'Turbolinks-Referrer: https://forwarded-host-demo-default.herokuapp.com/' --compressed -H 'X-Forwarded-Host: evil.com'
<!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 default_url_options workaround, the root_url is again on evil.com:

curl 'http://forwarded-host-demo.herokuapp.com/' -H 'If-None-Match: W/"254e9ac6e6fdf70d3db343af2e14544f"' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-GB,en-US;q=0.8,en;q=0.6' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8' -H 'Cache-Control: max-age=0' -H 'Cookie: _forwarded_host_session=MHNLQ3IzRUU2bXpyNEhFdSt5M3M4MzV3VkpPTnF2emJ6NFJWeFlJYXB2dmdlQ1IzeHNsMXpqUXJNdHFwWndFZ05hcmxvZloxRi8vejdnYzNEclNrK1VGdnVzZGpVM0RnMFFkUVdsL1V5cHh0akpSQkNXN0xWUURWYU5GRVFrWVhZVVZGZWdoVkxaSE5iclIvY29DK29BPT0tLUhhSlpFQk53clFDL0FrQnNpZW9zRnc9PQ%3D%3D--90e765814b25d1b640f35dce1d4ed9b15716ac09' -H 'Connection: keep-alive' --compressed  -H 'X-Forwarded-Host: evil.com'
<!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:

  1. In the default configuration, both root_url and request.host can be controlled by the attacker. (Edit: As pointed out above, the bad root_urls used in views can be cached in the rails page cache, which seems like the most serious problem.)

  2. The default_url_options workaround brings root_url back under the application's control, but request.host remains under the attacker's control, which leaves possible open redirects. (Edit: Rails page caching won't cache these redirects, but downstream caches might, which was the issue mentioned in https://hackerone.com/reports/487 . I'd therefore say this workaround is a good one, but it is not a complete workaround.)

Finally, I'd also note that the other workaround I suggested, which was to strip the X-Forwarded-Host header, is also implemented in this gem: https://github.com/pusher/rack-headers_filter --- they also seem to have had this problem and found the same solution (strip the headers).

I'll also edit my comment above to make note of these points. Thanks again!

@rails-bot
Copy link

rails-bot bot commented Nov 1, 2017

This issue has been automatically marked as stale because it has not been commented on for at least three months.
The resources of the Rails team are limited, and so we are asking for your help.
If you can still reproduce this error on the 5-1-stable branch or on master, please reply with all of the information you have about it in order to keep the issue open.
Thank you for all your contributions.

monfresh added a commit to codeforamerica/ohana-api that referenced this issue Feb 4, 2018
monfresh added a commit to codeforamerica/ohana-api that referenced this issue Feb 4, 2018
monfresh added a commit to codeforamerica/ohana-api that referenced this issue Feb 4, 2018
monfresh added a commit to codeforamerica/ohana-api that referenced this issue Feb 4, 2018
monfresh added a commit to codeforamerica/ohana-api that referenced this issue Feb 5, 2018
@m1foley
Copy link

m1foley commented May 10, 2018

A vulnerability scanner just hit my site with this exploit. The redirect was implemented like get "/foo", to: redirect("/bar") and this is still an issue on Rails 5.1.6.

@david-a-wheeler
Copy link

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.

@soundasleep
Copy link

soundasleep commented Sep 3, 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 X-Forwarded-For to generate redirection URLs) is still unsafely present.

We've found that defining a whitelist of valid hosts works best, by blocking malicious clients setting either Host or X-Forwarded-For headers. This works better than rack-headers_filter when using reverse proxies, and also handles a malicious client setting Host.

Include this in your ApplicationController:

  before_action :block_unknown_hosts

  SAFE_HOSTS = [
    "",
    "domain.com",
    "www.domain.com",
    "localhost", # for reverse proxy
  ]

  class NotASafeHostError < StandardError; end

  # We need to be able to trust the provided Host header, so that we can safely redirect
  def block_unknown_hosts
    unless SAFE_HOSTS.include?(request.host)
      raise NotASafeHostError, "#{request.host} is not a safe host"
    end
  end

@albinowax
Copy link

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.

@gsamokovarov
Copy link
Contributor

We already have a bit of work-in-progress code to guard against basic host header attacks in #33145. If you folks have ideas how we can handle the X-Forwarded-For or X-Forwarded-Host headers, please consider dropping a note in the PR above.

@kingdonb
Copy link

kingdonb commented Dec 5, 2018

So, in our environment, we usually overwrite all of the Host headers with the app's canonical host at the Load Balancer (nginx), but on the app I'm working on, we wanted for one single app to serve up the same content with two different configurations, depending on which URL you hit.

So we disabled the Host Header overwriting config in our nginx server, and carefully configured the app to only pay attention to the request.headers['SERVER_NAME'] variable when deciding which configuration to serve up. This seems to be the recommended way to mitigate these kinds of attacks.

But, from our vulnerability scanner, we are still vulnerable, and it seems to be the same issue as in this report. For me, the code that triggered this report from our vulnerability scanner was a redirect with a path helper, as I think others have reported:

redirect_to some_kind_or_other_path

I guess 302 redirects are required to include an absoluteURI, so even though I haven't explicitly invoked a URL helper, Rails decides that it must pull a URI from somewhere. I am getting a full URL (using X-Forwarded-Host header value eg. evilhost.com, value which should not be trusted.)

I implemented the middleware described at the top level of this thread to strip X-Forwarded-Host on the application, and I suspect this will solve it for our scanner, will know soon pending the next scan results.

I've read that SERVER_NAME is not guaranteed to be defined, but in our configuration at least, Nginx will definitely define it, and we can use it for what we need to know (what app name was this requester using, or "what name am I called," from the allowed hosts defined in the nginx vhost.)

We could probably configure Nginx to strip out X-Forwarded-Host too, for a solution that would not require adding a new middleware to each and every one of our Rails apps.

I think the solution is highly specific to my particular front-end load balancer configuration. #33145 looks like a really well thought-out solution, I like it, but I'm not sure if there's another solution that would not require me to maintain a separate whitelist in my nginx vhost block's server_name directive, and another one in my Rails app.

The advice I'm reading indicates that certain values like ServerName can be trusted if they are coming from your own front-end HTTP server. I'm not sure there's a way to generalize that for Rails apps that might not be running behind any front-end server, or behind a basic eg. ELB "Layer 4".

@mmustala
Copy link

Just ran into an issue where a missing HTTP_X_FORWARDED_HOST header prevents mounting engine routes. See sidekiq/sidekiq#4080 for details.

@mmustala
Copy link

I found a solution for mounting routes. I used to remove the HTTP_X_FORWARDED_HOST from the headers but if I just set it to the default host the routes are mounted. I suppose this also mitigates the security risk.

class StripXForwardedHost
  def initialize(app)
    @app = app
  end

  def call(env)
    default_url_options = Rails.application.config.action_controller.default_url_options
    env['HTTP_X_FORWARDED_HOST'] = (default_url_options && default_url_options[:host]) || nil
    @app.call(env)
  end
end
config.middleware.use StripXForwardedHost

@shyam-habarakada
Copy link

We ran into this issue as well and had to apply a solution similar to what others have recommended above, by implementing and applying a header sanitization filter in the form of a rack middleware. While that worked, the fact the request.hsot is unsafe by default isn't great and I am wondering what if anything rails could do to help address that for the thousands of unaware developers that use request.host. A couple of thoughts I had along those lines,

  • Make it secure by default
  • Allow overriding the default behavior

We could accomplish both by allowing a new configuration option that has a sensible default and allows overriding.

Rails.application.config.action_controller.host_validation = [ "domain.com", "*.domain.com" ]

Thoughts?
And do we think that this is best implemented a rack middleware?

I can submit a PR based on feedback.

@rromanchuk
Copy link

FYI re:config.hosts just found out the hard way that this is enabled/disabled based on the existence of config.hosts being defined. I accidentally included a host in production.rb conflating it with another issue. Didn't notice until the load balancer dropped my rails6 test machine because of failed healthchecks, was confusing to track down at first because the denials weren't being logged anywhere obvious, at least not where I was looking.

I guess my assumption was if i had to add localhost to development env in order for it to work, i forsure needed to add my hosts to production.rb Might be nice to have an explicit on/off boolean or deployment docs, for example i terminate SSL at an AWS application load balance than it's forwarded on to port 80 behind my VPC. I'll read the RTFM/code, but probably needs some more docs around the 5.2 -> 6.0 upgrade guide docs

@jdleesmiller
Copy link
Author

Now that rails 6 is out and provides Rails.application.config.hosts (#29893 (comment)), I think we can close this. (But of course the maintainers can reopen it if I'm wrong about that.)

brucebolt added a commit to alphagov/govuk-coronavirus-business-volunteer-form that referenced this issue Apr 2, 2020
If a user sets an X-Forwarded header in a request, this will in some
cases override the Host header in a Rails app, resulting in URL
redirection to a different website. If an attacker manages to poison a
cache with such a header, users will be redirected to malicious sites.

In rails/rails#29893, the resolution is to set
config.hosts.  Therefore setting this for all environments in this app.
brucebolt added a commit to alphagov/govuk-coronavirus-vulnerable-people-form that referenced this issue Apr 2, 2020
If a user sets an X-Forwarded header in a request, this will in some
cases override the Host header in a Rails app, resulting in URL
redirection to a different website. If an attacker manages to poison a
cache with such a header, users will be redirected to malicious sites.

In rails/rails#29893, the resolution is to set
config.hosts.  Therefore setting this for all environments in this app.
brucebolt added a commit to alphagov/govuk-coronavirus-business-volunteer-form that referenced this issue Apr 3, 2020
If a user sets an X-Forwarded header in a request, this will in some
cases override the Host header in a Rails app, resulting in URL
redirection to a different website. If an attacker manages to poison a
cache with such a header, users will be redirected to malicious sites.

In rails/rails#29893, the resolution is to set
config.hosts.  Therefore setting this for all environments in this app.
brucebolt added a commit to alphagov/govuk-coronavirus-vulnerable-people-form that referenced this issue Apr 3, 2020
If a user sets an X-Forwarded header in a request, this will in some
cases override the Host header in a Rails app, resulting in URL
redirection to a different website. If an attacker manages to poison a
cache with such a header, users will be redirected to malicious sites.

In rails/rails#29893, the resolution is to set
config.hosts.  Therefore setting this for all environments in this app.
brucebolt added a commit to alphagov/govuk-coronavirus-vulnerable-people-form that referenced this issue Apr 3, 2020
If a user sets an X-Forwarded header in a request, this will in some
cases override the Host header in a Rails app, resulting in URL
redirection to a different website. If an attacker manages to poison a
cache with such a header, users will be redirected to malicious sites.

In rails/rails#29893, the resolution is to set
config.hosts.  Therefore setting this for all environments in this app.
brucebolt added a commit to alphagov/govuk-coronavirus-vulnerable-people-form that referenced this issue Apr 3, 2020
If a user sets an X-Forwarded header in a request, this will in some
cases override the Host header in a Rails app, resulting in URL
redirection to a different website. If an attacker manages to poison a
cache with such a header, users will be redirected to malicious sites.

In rails/rails#29893, the resolution is to set
config.hosts.  Therefore setting this for all environments in this app.
jdoss pushed a commit to forem/forem that referenced this issue Jun 2, 2020
… localhost

or 127.0.0.1. Pretty sweet huh?

The reason for this change is because I want to easily get to these healthcheck
end points from localhost without having to get the health-check-token beforehand.

Buttttt.... this addition has some issues. You can spoof the host header pretty
easily:

https://daniel.haxx.se/blog/2018/04/05/curl-another-host/

I thought about doing `return if !request.ssl? && request.local?`

to check of the request was over https or not. Any localhost healthcheck we do
directly to puma will be over http. Checking for TLS seemed like a logical next
check, but since we force https on the edge and not necessarily from the edge to
Puma the Host header can still be spoofed to get at these end points.

More info on host header attacks and what Rails 6 is doing about it:

rails/rails#29893

While I do think it is a good idea to protect these healthcheck end points from
the outside world, I do want to be able to get to them easily locally. WWYD?
benhalpern pushed a commit to forem/forem that referenced this issue Jun 2, 2020
…th-check-token (#8231)

* This change allows access to api/health_checks if you are coming from localhost
or 127.0.0.1. Pretty sweet huh?

The reason for this change is because I want to easily get to these healthcheck
end points from localhost without having to get the health-check-token beforehand.

Buttttt.... this addition has some issues. You can spoof the host header pretty
easily:

https://daniel.haxx.se/blog/2018/04/05/curl-another-host/

I thought about doing `return if !request.ssl? && request.local?`

to check of the request was over https or not. Any localhost healthcheck we do
directly to puma will be over http. Checking for TLS seemed like a logical next
check, but since we force https on the edge and not necessarily from the edge to
Puma the Host header can still be spoofed to get at these end points.

More info on host header attacks and what Rails 6 is doing about it:

rails/rails#29893

While I do think it is a good idea to protect these healthcheck end points from
the outside world, I do want to be able to get to them easily locally. WWYD?

* Fix Health Check spec by stubbing request

Co-authored-by: mstruve <mollylbs@gmail.com>
camallen added a commit to camallen/Panoptes that referenced this issue Jun 5, 2020
avoid user control of the host header used in rails to create links that can direct to malicous URLs,  rails/rails#29893
camallen added a commit to camallen/Panoptes that referenced this issue Jun 5, 2020
pass the server_name to the proxy's request to avoid malicious user controlled links, rails/rails#29893
adammcmaster added a commit to zooniverse/panoptes that referenced this issue Jun 11, 2020
* Remove X-Forwarded-Host header

Carrying over zooniverse/operations#283

* use correct staging server_name

* manually set the X-Forwarded-Host to our servername

avoid user control of the host header used in rails to create links that can direct to malicous URLs,  rails/rails#29893

* split out server blocks to provide unique server_names

pass the server_name to the proxy's request to avoid malicious user controlled links, rails/rails#29893

Co-authored-by: Campbell Allen <campbell.allen@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

14 participants