Rails 3+の環境変数の一部をフィルタリングする
基本設定と動作
Rails にはもともと log などに sensitive な情報が残らないようにするための設定がある
Ruby on Rails Guides: Configuring Rails Applications
config/application.rb 内の
config.filter_parameters += [:password]
この設定は最終的に ActionDispatch::Http::FilterParameters の中の
- filtered_parameters
- filtered_env
に適用されて、不必要な情報をフィルタした結果を取得できるようになっている。
環境変数の除外設定は単に変数名を指定するだけ
この filtered_env に渡したくない環境変数を設定するには単に名前を指定するだけでよい。例えば AWS 関連の複数の環境変数の値をフィルタリングしたければ以下のようにすればよい。
config.filtered_parameters += [/^AWS/]
AWS 関連の情報を AWS_* という名前で環境変数にセットしているものとする。例えば AWS_S3_BUCKET, AWS_REGION みたいな感じ。1
development環境で環境変数が確認できないので意図せず秘密情報が漏洩してるかも
ところがこの環境変数を除外できたかどうかが development 環境2での request.env と request.filtered_env の比較では確認することができなかった。確認する方法をご存知の方はぜひ教えてください。これ、割と困ります。3
rack に入っている HTTP_* や SERVER_* は確認できるんだけど、rails server を起動する shell で export した環境変数の値は、何も除外していないはずの env でも取得できない。ENV からは取得できるんだけど。
上の方法では development 環境で確認することができないが、例えば Apache + Passenger の production 環境では Apache から渡している環境変数の中からちゃんと除外してあげないと filtered_env の中に AWS 関連の設定が全部残ってしまう。
環境変数は普通 log に残らないし、別にいいんじゃないのと思うかもしれないが、これで何が困るのかというと、Exception Notification などに丸ごとの環境の情報が渡ってしまう。本来あちこちに残ると好ましくない情報が拡散されてしまうのでこれはフィルタリングしておきたい。
その他にも Exception Notification にはデフォルトの設定が緩いのではないかという指摘があったりする
ので、AirBrake など他のサーバを利用した監視を行っている人も環境変数の値などが不必要に渡っていないか確認した方がいいかも。