Railsでのセキュリティリスクとその対策

代表的なセキュリティ攻撃とRailsでの対策を復習

CRSF(クロスサイトリクエストフォージェリ)

ログインした状態(セッションIDを維持した状態)を悪用してリクエストすること
ログイン後の利用者のみが利用可能なサービスを悪用したり(不正送金や商品購入、退会)、編集可能な情報を改竄できてしまう。
ログインした状態で不正なリンクをクリック。Webサイトを移り(クロス)、ユーザーの要求を偽って(フォージェリ)、悪意のあるリクエストが送信される

対策

  • GET/POSTを正しく使うこと
    GETは情報読み出し、POSTは状態変化や何らかの作用を伴う操作

  • GET以外のリクエストにはセキュリティトークンを使う
    リクエストがユーザーの意図にあるものかを確認するために、同じWebアプリから生じたリクエストであることを証明するためのセキュリティトークンを発行、照合する
    config.action_controller.default_protect_from_forgeryをtrueに設定すると自動的に実行(Rails5.2からデフォルトの設定)
    form_withなどを使ったリクエストは自動でセキュリティトークン(authenticity_token)が埋め込まれる

Ajaxリクエストへのセキュリティトークンの埋め込み
Ajaxリクエストでセキュリティトークンを送るには、JavaScriptが動く画面内にあらかじめセキュリティトークンを出力しておき、そのトークンを使ってX-CSRF-TokenというHTTPヘッダーで送る必要がある
出力はアプリのviewにある<%= csrf_meta_tags %>
fetch APIAjaxリクエストを送信する場合は自分でトークンを埋め込む必要がある

fetch('/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json; charset=utf-8',
    'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
  }
})

XSS脆弱性があると、あらゆるCSRF保護が迂回されるので注意

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

テキストフォームなどの出力処理に問題がある場合に、スクリプトなどを埋め込まれてしまう
フィッシング詐欺(別サイトへ誘導)、セッションハイジャック(cookieを取得しなりすましができる)

対策

  • RailsXSS対策が標準で組み込まれていて、view処理を実行した際にHTMLタグに対してエスケープ処理が行われる。
    &,",<,>は、&amp;,&quot;,&lt;,&gtにそれぞれ置き換えられる
  • HTMLのエスケープ回避したいときのメソッド(html_safe/raw(<%==))を使う場合は、脆弱性が発生することになるので注意。html_escapeを使ってエスケープ。
  • ある程度タグをそのまま出したいが、危険なタグを出力したくない場合はSanitize Helperホワイトリスト方式で制限。

SQLインジェクション

パラメーター操作でDBをさわれてしまう
RailではSQL文字をフィルタする仕組みがあり', ", NULL, 改行をエスケープされるので、滅多に起こらなくなった。 Model.find(id)Model.find_by()といったクエリでは自動的にこの対策が適用されるが、
where("...")connection.execute()Model.find_by_sql()については手動でエスケープする必要あり

対策

# クエリメソッドに対してハッシュで条件を指定
users = User.where(name: params[:name])
# プレースホルダを利用
users = User.where('name = ?', params[:name])

LIKEは演算子は自動的にサニタイズされないので注意。sanitize_sql_likeを使う必要がある

参考

学んだことがあれば都度追加していく。