Railsで必要なセキュリティ対策を調べてみた

スポンサーリンク

Ruby on Railsでwebアプリケーションを作っているのだが、ログインシステムを実装する以上、ユーザIDやパスワードの盗難などが心配になってきた。

そこで、Railsで必要なセキュリティ対策を、代表的な攻撃をもとに調べてみたので、まとめておく。
(誤り等があればコメント欄でご指摘をお願い致します)

参考にしたサイトは以下の通り。
フレームワークに見る Web セキュリティ対策
Rails セキュリティガイド

セッションハイジャック

=IDとパスワードを盗まれ、なりすましログインされる攻撃。

<対策>
・SSLを導入する。

管理者になりすましたログイン

=セッションハイジャックのひとつだが、管理者がジャックされると非常に深刻な影響が想定される。

<対策>
・管理者権限を1ユーザに限定せず、複数に分散させておく。
・特に重要な操作をするときは、別の特別なパスワードを求める。
・管理者画面はサブドメインを作成して別サイトとする。
・管理者ログインはIPアドレスを制限する。(プロキシで偽装されれば無意味だが、やらないよりはやった方がいい)

セッション固定攻撃

=ログイン前にセッションIDを発行してしまうサイトで、攻撃者が事前にログイン画面等で取得したセッションIDのパケットを、対象者がログインする際に差し込まれてしまうと、そのセッションIDでログインしてしまう。そうなると、攻撃者はそのセッションIDを知っているので、ログイン後のページにアクセスできてしまう。

<対策>
・ログイン前にセッションIDを発行しない。
・ログイン後にセッションIDを発行する場合は、その前に必ずreset_sessionをはさむ。

アカウントジャック

=セッションハイジャックに近いが、パスワード等が何らかの手段で盗まれると、アカウントがジャックされてしまう。

<対策>
・パスワード変更の際は古いパスワードも入力させる。
・メールアドレス変更の際もパスワードを入力させる。

リクエスト強要(CSRF)

=サーバが偽のページから送られたフォーム送信などを受取り、それを受理してしまうと、不正にDBが改ざんされたりする攻撃。

<対策>
・Railsでは、自動でフォームのhiddenフィールドとしてランダム値を埋め込んでいるため、偽装コンテンツからのリクエストを受け入れることはない。そのため、対応不要。

クロスサイトスクリプティング(XSS)

=フォームにJSやHTMLを入力されることで、悪意ある操作(別のサイトへリダイレクト、cokkieを攻撃者サイトに送信など)をされる攻撃。

<対策>
・Railsでは自動でHTMLタグ等(<や>や&)はエスケープするようになっているため、対応不要。
・以下をフォームに入力してみることで簡単にチェック出来る。
 <script>alert(‘Hello’);</script>

SQLインジェクション

=フォームにSQL文を入力され、サイトがその値をそのまま使ってSQLを作っていたりすると、不正にSQL操作される攻撃。

<対策>
・ActiveRecordのメソッドや、プレースホルダを使う。それらは、SQL生成の際に自動でエスケープしてくれる。

Mass Assignment脆弱性

=フォームから受信したパラメータを一括でテーブルに登録しようとしたときに、攻撃者がフォームにはないテーブル項目を追加してsubmitした場合、サイト制作者が意図していない項目まで登録・更新されてしまう攻撃。

<対策>
・Mass Assignmentを使わず、1つずつの項目を指定してinsert・updateする。
・Mass Assignmentを使う場合は、ストロングパラメータ(permit)を使って、受け付ける項目を制限する。

DBからのパスワード漏洩

=何らかの方法でDBの内容を盗まれた場合(SQLインジェクション・DBアカウント乗っ取り・DBのハードごとの盗難)、パスワードを盗まれてしまう。

<対策>
・Digest::SHA2.hexdigest等でパスワードをハッシュ化してから格納

ログからのパスワード漏洩

=ログファイルにログイン時のパスワードを書き込んでいる場合、ログファイルが何らかによって盗まれた時に、パスワードを盗まれてしまう。

<対策>
・/config/initializerz/filter_parameter_logging.rb に Rails.application.config.filter_parameters += [:password] と書いておくと、paramsに:password項目があった場合、[FILTERED]とマスク化されて表示される。

ユーザリストを作成される

=ログイン画面のエラーで「そのユーザは登録されていません」というメッセージを出力するアプリケーションの場合、適当に入力したIDが存在するかどうかがバレてしまう。その場合、総当たり攻撃を仕掛けられ、そのメッセージが表示されないIDのみ有効なIDとして収集されてしまう。

<対策>
・一般的な「ユーザー名またはパスワードが違います」というメッセージだけ出力し、どちらを間違ったのかわからないようにする。
・「パスワードを忘れた時」ページも同様の一般的なメッセージにする。

自動ボットによる不正ユーザ新規登録

=自動ボットによって、不正にユーザIDを作られてしまう。

<対策>
・CAPTCHA(歪んだ文字列)を入力させて防ぐ。(ReCAPTCHA API)
・ネガティブCAPTCHA(見えない所に表示させたテキストフィールドなど=ハニーポッド)に何か入力されていたらボットと判断。

URLの正規表現の脆弱性

=「^」や「$」は文字列全体ではなく行でマッチングしてしまうので、1行目に悪意のあるJSが書かれていても、2行目がマッチングしてしまったらフィルタを通って実行されてしまう。

<対策>
・より安全な「\A」や「\z」を使用する。

URLを変更して不正なページにアクセス

=末尾の/idなどを書き換え、別のユーザのページなどに不正にアクセスされる。

<対策>
・ログインユーザを判断し、許可されていないユーザには表示できないようにするなど。

HTTPヘッダへの悪意コードの挿入

=HTTPヘッダに悪意コードが挿入され、それを使用する処理があった場合に実行されてしまう。

<対策>
・最新のRailsでは自動でエスケープされるようになっている?
・念のため、ヘッダ情報は使わないようにする。

まとめ

【Railsが自動で対処してくれるもの】
・リクエスト強要(CSRF)
・クロスサイトスクリプティング(XSS)
・SQLインジェクション

【環境で対策する必要があるもの】
・SSLを導入する
・ログファイルのパスワードをフィルターをかける
・管理者画面はサブドメインを作成して別サイトとする。
・管理者ログインはIPアドレスを制限する。
・管理者権限を1ユーザに限定せず、複数に分散させておく。

【コーディングで対処する必要があるもの】
・ログイン前にセッションIDを発行しない。
・ログイン後にセッションIDを発行する前にreset_sessionをはさむ。
・Mass Assignmentを使わない。(使う場合はストロングパラメータを使う)
・DBへのパスワード保存はハッシュ化してから。
・特に重要な管理者操作をするときは、特別なパスワードを求める。
・ユーザID・パスワードの相違時は、どちらが間違ったかわからないメッセージを表示。
・パスワード変更・メールアドレス変更時は、古いパスワードの入力を求める。
・新規ユーザ登録ページにはReCAPTCHAを導入する。
・正規表現では「^」や「$」は使わず、「\A」や「\z」を使う。
・URLを書き換えてリクエストされても、意図しないページにはアクセス出来ないように対応。
・HTTPヘッダの内容は使用しない。(使用する場合は別途安全な方法を調べて下さい)


スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です