Railsのセキュリティに関するチートシート


シーエー・アドバンス Advent Calendar 2018 24日目担当の @togana です。

Rails で開発時に気をつけるべきことをまとめました。
breakman を動かすだけでも問題点を見つけるとができるので、チートシート読み飛ばして試してみてほしい。

対象

  • Railsで開発したことがある人
  • バージョンは4以降

チートシート

  • クロスサイトスクリプティング (XSS)
    • coffee scriptなどで起きるやつは Rails とは異なるのでこの記事では対象外とする
    • 対象はerbなどのテンプレート側
    • 問題になりやすい下記のメソッド名で grep して問題ないか目視する(そもそも使ってる場合は怪しい)
      • html_safe
      • raw
  • SQL インジェクション
    • ほとんどの場合デフォルトで対策されている
      • 「’」「“」NULL、改行に関しては自動でエスケープされる
    • LIKE検索のときはすこし気をつける
      • 「%」および「_」及び「\」をエスケープしたい場合は sanitize_sql_like メソッドを使用する
    • クエリを文字列で送っている場合かつ入力値をそのまま入れている場合は問題が起きやすいので注意
      • どうしても手動でエスケープせざるを得ない場合は sanitize_sql メソッドを使用することを検討する
    • こういうものもあるらしい: Rails 5.2で"Dangerous query method ..."の警告が出たからといって、機械的にArel.sqlを適用してはいけません。
    • 後述する breakman で大抵検知できる
  • OS コマンドインジェクション
    • 問題になる下記のメソッド名で grep して問題ないか目視する
    • system
    • eval
    • `
    • Kernel.exec
    • 後述する breakman で大抵検知できる
    • open メソッドを利用したケースもあるので気をつける
result = open("| ls -lh")
while !result.eof
  print result.gets
end
result.close
  • セッション管理
    • デフォルトの設定だとcookieセッションを利用するのでサーバ側で保持していないのでセッションをサーバ側で消すことが不可能
      • redis を使う、もしくは active_record_store を使うようにする
    • apiモードはデフォルトでは Cookie が使えないようになってるので jwt とかその他認証方法も検討する(要件に合わせて検討しましょう)
  • クロスサイトリクエストフォージェリ (CSRF)
    • 基本的にはデフォで対応されている
    • apiモードはデフォルトで対策が除外されているので注意
  • クロスオリジンリソースシェアリング (CORS)
    • rack-cors を使ってホワイトリスト指定する
  • セキュリティ関連ヘッダー
    • デフォルトで下記に対応している
    • 'X-Frame-Options' => 'SAMEORIGIN'
    • 'X-Content-Type-Options' => 'nosniff'
    • 'X-XSS-Protection' => '1;'
    • コンフィグで下記設定するとHSTSの設定もできる
    • config.force_ssl = true
    • nginxなどで設定したら2重に設定されないかとか確認する必要あるかもしれない(要検証)
  • アクセス制御(権限で保護されていない直接的な参照など)
    • cancancanpundit などを使う(権限による設定ができる)
  • 機密のファイル
    • Rails5から暗号化する仕組みとか入ったから使うのもあり
    • 5.1と5.2で仕様違うから注意!
    • masterパスワード漏れたら全滅なので慎重に管理しましょう
    • 間違っても機密情報をプッシュしないために ignore 設定はちゃんとしましょう
      • https://www.gitignore.io/api/rails
        • ↑だとlogディレクトリとtmpディレクトリがプッシュされないので.keepファイルは許可するように書き換えると便利(たまにgit pull して動かなくて焦る)
  • ビジネスロジックのバグ
    • スピリチュアルプログラミング(反面教師にしましょう)
    • コードレビューをしっかりする
    • 単体テストをちゃんと書く

breakmanの紹介

Dockerで実行する例
プロジェクトのカレントディレクトリで下記コマンドを実行する
(winでもdocker-for-windowsいれてパワーシェルで試したら動いたので気軽に試せてよい)

$ docker run -v "$(pwd):/code" presidentbeef/brakeman -o brakeman_results.html

brakeman_results.html に結果が出てくる
このコードが悪いってとこまで教えてくれる。便利!
(キャプチャは意図的に脆弱性を組み込んだサンプルアプリに対して実行しています)

まとめ

Breakman 使うとうっかり作り込んでしまった脆弱性に気づけるので気軽に CI に入れるとよさそう。
意識することですこしは安全な世界になると思うのでチートシート眺めて参考にしていただければ!

紹介した gem とか

もっと意識高くセキュアにコード書きたい人への参考リンク