Rails 6 adds guard against DNS rebinding attacks

1 minute read

Rails 6 has added guard against DNS rebinding attacks by allowing whitelisting of hosts in config. The guard is active by default for development environment and can be availed optionally for other environments.

What is a DNS rebinding attack?

A DNS rebinding attack occurs when the attacker uses a web page to run malicious client side script to sneak into victim’s network and use their browser as a proxy to attack devices on the same network.

How does this affect my Rails app?

The attacker can use DNS Rebinding to perform remote code execution (RCE) on the Rails application running locally. With the correct approach, the attacker can gain access to our local ENV information and all information about the local Rails app.

In Rails 6

If we try to access a Rails 6 app in development environment with a custom domain (ngrock, lvh.me or by simply editing the hosts file), it is likely that we will get the following error:

Blocked host: yourcustomdomain.com

But accessing the app via localhost works just fine! The reason behind the error is Rails trying to prevent the app from DNS rebinding attacks with the help of ActionDispatch::HostAuthorization middleware. It is included in development environment by default with following configuration,

Rails.application.config.hosts = [ IPAddr.new("0.0.0.0/0"), # All IPv4 addresses. IPAddr.new("::/0"), # All IPv6 addresses. "localhost" # The localhost reserved domain. ]

To allow a custom domain, we can add the domain in hosts config. For instance, in development.rb :

# Allow requests from domain 'yourcustomdomain.com' Rails.application.config.hosts << 'yourcustomdomain.com'

To allow requests from subdomains,

# Allow requests from subdomains like 'www.yourcustomdomain.com' # and 'blog.yourcustomdomain.com'. Rails.application.config.hosts << '.yourcustomdomain.com'

And if we need to bypass the guard altogether and allow requests from any domain,

# Allow requests from any domain Rails.application.config.hosts = nil

Note that for environments other the development, config.hosts is empty by default. This means no domain checks will be done and the guard will be inactive.