11.1 インジェクション対策
ホワイトリストとブラックリスト
許可しないものをリストアップしたブラックリストと逆の意味のホワイトリストを使うのはRailsのセキュリティ対策での基本で、まずホワイトリスト意識しながら設計するのが有効です。
たとえば、before_action
ではexcept
を使うよりもonly
オプションを使う、などです。
SQLインジェクション
Railsには'
、"
、NULL
、改行
などのSQLにおいて特殊な意味を持つ文字をエスケープする機能があります。
SQLインジェクションの対策としては以下のように配列で条件を渡すことで文字列がサニタイズされます。
Post.where("status = ?", 'published').first
クロスサイトスクリプティング (XSS)
RailsのデフォルトではHTMLはエスケープ処理されます。エスケープをしたくない場合はraw
メソッドなどで出力することが可能です。
クライアントからの入力などは必ずエスケープが必要で、そのまま表示すると悪意のあるコード実行されてしまうことがあります。ユーザーからの入力html_escape
ヘルパーを利用しエスケープして表示するのが望ましいです。
CSSインジェクション
CSSにでJavascriptを実行することにより発生してしまうインジェクションです。主にユーザーがCSSをカスタマイズすることができるサービスで起こり得ます。
対策としてシンプルにユーザーが直接CSSをいじることをできなくするのが早いでしょう。どうしても必要であれば、CSSをRailsのsanitize
メソッドを使用してサニタイズすることもできます。
Ajaxインジェクション
Ajaxでビューのレンダリングをする場合でもエスケープされている必要があります。
Javascriptでビューの一部を書き換えたり、要素を出力する場合でもXSS対策同様html_escape
メソッドを使ってエスケープしましょう。
コマンドラインインジェクション
ユーザーが入力した値をコマンドラインのオプションに使用する場合は十分に注意が必要です。
Rubyではexec
、syscall
、system
などのメソッドが用意されており、OSコマンドを実行できます。
悪意のあるコードを防ぐ対策としてはsystem
メソッドを利用することです。
リダイレクション
リダイレクトと実行するredirect_to
メソッドに不正なパラメータが渡されてしまうと意図しないサイトに遷移してしまうのに加え、Referer
情報などが漏洩してしまう恐れがあります。
これを対策するにはホワイトリストでredirect_to
メソッドに渡すパラメータを制限する必要があります。
権限のスコープ
ログインしているユーザーしか操作を許可されていないにも関わらず、他のユーザーが操作をできてしまうのは危険です。
対策するには現在のユーザーのみのスコープに絞る必要があります。
@post = Post.find(params[:id]) # NG
@post = current_user.posts.find(params[:id]) # OK