Rails6でBlocked hostエラーが発生した時の対処法

この投稿は、弊社が提供するWESEEK TECH通信の一環です。
WESEEK TECH通信とは、WESEEKのエンジニアがキャッチアップした技術に関する情報を、techブログを通じて定期的に発信していくものです。

関連記事

開発でのロックの重要性とORMのロック実現例〜楽観的ロックの利用例|フレームワーク O/R マッパー

開発でのロックの重要性とORMでのロックの実現例 |楽観的ロックの紹介

Ralisへ機能フラグ(Feature Flag)を追加し各フラグを制御する

エラーの内容

Rails 6 で、任意の host 名を指定してアクセスをしようとしたとき、下記のようなエラーが表示されることがあります。

Blocked host: hogehoge-host.com
To allow requests to hogehoge-host.com, add the following to your environment configuration:
    config.hosts << "hogehoge-host.com"

原因

Rails 6 から追加された、DNSリバインディング攻撃を防止する ActionDispatch::HostAuthorization middleware によるものです。

下記の Pull Request で実装されました。

Guard against DNS rebinding attacks by permitting hosts by gsamokovarov · Pull Request #33145 · rails/rails · GitHub

DNSリバインディング攻撃とは

攻撃者が、悪意のある Web サイトにユーザーを訪問させ、クライアント側でスクリプトを実行させます。
このとき、攻撃者は短時間にドメイン (FQDN) に対する IP アドレス (Aレコード) を脆弱性のある Web サイトに変更します。
FQDN は変化していないため、同一生成元ポリシーは保たれ、攻撃者の用意したスクリプトで、脆弱性のある Web サイトに対して攻撃を仕掛けることができます。

DNS rebinding - Wikipedia

対処法

1. Rails.application.config.hosts に接続先として許可する Host を追加する

development 環境では、 default で Rails.application.config.hosts に下記の Host が登録されています。
これ以外の Host 名として接続しようとすると、ブロックされるため、必要な Host 名を追加します。

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

追加方法は、 development 環境であれば、 config/environments/development.rb に下記のように記述します。

Rails.application.configure do
    config.hosts << "hogehoge-host.com"
end

2. Rails.application.config.hosts の設定を clear する

Rails.application.config.hosts は、空の場合は Host ヘッダーのチェックが行われないため、ブロックされなくなります。
development 環境以外の環境 (たとえば production ) では、 Rails.application.config.hosts は default で空のため、チェックは行われません。

development 環境で Host ヘッダーのチェックを行わないようにするには、 config/environments/development.rb に下記のように記述します。

Rails.application.configure do
    config.hosts.clear
end

なお、アプリケーションの前段に Host ヘッダーを識別して振り分けを行う LB 等がない場合は、DNSリバインディング攻撃が防止できなくなるため、 development 環境以外では Rails.application.config.hosts を適切に設定されることをおすすめします。

3. ActionDispatch::HostAuthorization middleware を使わないようにする

アプリケーションの前段に Host ヘッダーを識別して振り分けを行う LB 等があり、アプリケーション自体でDNSリバインディング攻撃を防止する必要がない場合は、 ActionDispatch::HostAuthorization middleware 自体をロードされないように設定します。

config/application.rb に下記のように記述します。

module HogeApp
  class Application < Rails::Application
    onfig.middleware.delete ActionDispatch::HostAuthorization
  end
end

まとめ

アプリケーションの前段に、 DNSリバインディング攻撃を防ぐ機構がある場合は、対処法 2 or 3 を、そうではない場合は対処法 1 を実施します。