基本的な脆弱性攻撃について(SQLインジェクション、XSS、CSRF)

【結論】

SQLインジェクションとは、
 フォームに直接SQLを入力する事で、  意図しないSQL文を実行させる攻撃手法

XSSとは、入力フォームなどを用いて
 WebページにJavaScriptなどのスクリプトを仕込み、
 意図しない動作を実行させる攻撃手法

CSRFとは、対象のWebサービスへのログイン状態が
 維持されたユーザーに、悪意あるスクリプトが組み込まれた
 URLをクリックさせる事で、ユーザーが意図していない操作を
 強制的に実行させる攻撃手法

【目次】

【本題】

脆弱性攻撃とは

ソフトウェアに、開発者が意図しない操作を実行させて、
本来出来ない様な情報の取得/改竄などを行う事を指します。

脆弱性は、セキュリティホールとも呼ばれています。
今回は、代表的な脆弱性攻撃と対策についてまとめます。

※参考URL
railsguides.jp

SQLインジェクション

アプリケーションが意図していないSQL文を実行させる事で、
本来アクセス出来ない情報の取得や改竄などを行う手法です。

実行されると、下記の様な問題が起こる可能性があります。
・データベース内の個人情報を取得する
・アカウント認証を回避してサービスを利用する
・別ユーザーになりすまして、サービスを利用する
・データベースの情報を削除して、サービスを機能しなくする

具体的な実行方法としては、
ログイン画面のユーザー名・パスワードといった
入力フォームに直接SQLを入力する方法です。

脆弱性があると、そのSQLをアプリケーションが実行してしまい、
その命令文に応じた処理を行ってしまいます。

対策

Railsの場合、findやwhereなどのメソッドが 指定した条件に基づいて、SQL文を生成します。

モデルクラスのインスタンスメソッドである 「find」「find_by」に関しては、「'」「"」「NULL」「改行」といった 特殊なSQL文字をエスケープする仕様が元々実装されています。

しかし、「where」「execute」「find_by_sql」に関しては、 その仕様が実装されていない為、手動でエスケープする必要があります。

なお、条件オプションで文字列を直接渡さず、 ハッシュか配列を渡すことで、汚染された文字列をサニタイズすることもできます。 サニタイズとは、特殊文字を一般的な文字列に変換する処理の事です。

↓例

○ハッシュ

User.where(name: params[:name], password: params[:password])

○配列

User.where(["name = ? and password = ?", params[:name], params[:password]])

×文字列

User.where("name = '#{params[:name]}', password = '#{params[:password]}'")

XXS

入力フォームなどを用いて
WebページにJavaScriptなどのスクリプトを仕込み、
意図しない動作を実行させる攻撃手法です。

クロスサイトスクリプティング と呼ばれる下記の様な攻撃を行います。
・クッキーの盗難による不正アクセス
・偽サイトに誘導してフィッシングでアカウント情報を不正取得
・不正なスクリプトを含むリクエストを送信し権限を変更

これを防ぐには、フォームで「<」「>」「?」などHTMLタグとして
認識される文字が入力された際に、エスケープさせる必要があります。

Railsでは、<%= %>というタグを用いれば、
文字列の変換が自動的に行われるような仕組みになっています。

CSRF

あるWebサービスへのログインが維持された状態で 悪意あるスクリプトが組み込まれたURLをクリックする事で、 ユーザーが意図していない操作を実行させる攻撃手法です。

ユーザーがURLをクリックすると、 ブラウザのCookieに保持されているログイン情報を用いて WEBサービスに強制的にアクセスさせ、
ユーザーの権限で実行できる様々な操作を行わせます。

Railsの場合、ApplicationControllerに
下記の記述を施す事で対策しています。

protect_from_forgery with: :exception

これはアプリのフォームに対してトークンを発行するコードで、 フォーム送信時にこのトークンも合わせて送信する事で、 正しいフォームからの通信なのかを判別することができます。

これにより、Cookieに保持されたセッション情報だけで
WEBサービスにアクセス出来ない様になっています。