Any harm in adding localhost to config.hosts in production?

I’m deploying a Rails app to a Caprover server. To have zero-downtime deploys, the Dockerfile needs a health check. What I have now is an endpoint returning nothing but a status 200 response:

HEALTHCHECK \
  --interval=20s --retries=5 \
  CMD curl --fail localhost:3000/ops/health || exit 1

For this to work, 'localhost' is required in config.hosts; otherwise, it’ll return a Connection refused error.

The setup works, but I’m wondering if there’s any harm in adding localhost in a production environment. I guess not, but maybe I’m overlooking something.

1 Like

It’s probably not a good idea. The whole point of the hosts config is to safely lock down the permissible hosts to an approved list: adding localhost to production probably opens up attacks from attackers from the public internet spoofing localhost in the DNS. And localhost is very likely a DNS they would want to impersonate…

However, the Host authorization checker is just a Rails middleware.

One approach could be to just create your own simple middleware for health checks, and insert it into the middleware stack before the HostAuthorization middleware, and have your new middleware just call the controller /ops/health is calling directly.

Maybe something like this (untested):

# A simple middleware who's `call` looks something like this:
def call(env)
  req = Rack::Request.new(env)
  if req.path == '/ops/health'
    OpsController.action(:health).call(env)
  else
    @app.call(env)
  end
end

Then in your production.rb:

# This would put it right at the top of the stack, before everything else. You may just want it before `HostAuthorization`
config.middleware.insert_before 0, "MyHealthChecker"
1 Like

Or you can opt-out of Host Authorization with exclude

config.host_authorization = { exclude: ->(request) { request.path =~ /healthcheck/ } }
1 Like