セキュリティ対策(XSS, CSRF, SQLインジェクション)

PHPの代表的なセキュリティ(XSS、CSRF、SQLインジェクション、セッション固定攻撃)の概要と対策について書いてます。

XSS
( Cross Site Scripting )

概要

XSSの対策をしないと、悪意ある外部サイトから自分のサイトに悪意ある設定をしたリンクを貼られます。そのリンク経由で自分のサイトに訪れたユーザは自分のサイトを開いた際、悪意あるスクリプトが実行されてしまいます。XSSの脆弱性は、フォームから入力された情報をそのまま画面に表示するサイトなどに存在します。

対策

変数を出力する際にhtmlspecialchars関数でエスケープを行い、スクリプトを無効化します。

string htmlspecialchars ( string $string, int $flags, string $encoding )
引数 概要
$string 変換対象文字列
$flags 引用符の変換方法(ENT_QUOTESを指定しないとシングルクォートがエスケープされないので注意)
$encoding 文字エンコーディング
echo htmlspecialchars($str, ENT_QUOTES, "UTF-8");

CSRF
( Cross Site Request Forgeries )

概要

CSRFの対策をしないと、下記のように利用者アカウントで重要な処理が実行されてしまいます。

1. CSRFの脆弱性をもつ通販サイトにログイン
2. 1の通販サイトにログインした状態のまま、通販サイトに攻撃を仕掛けようとしている罠サイトにアクセス
3. 罠サイトから通販サイトに対して、物品購入のリクエストを送信

※ユーザは通販サイトにログインした状態のままなので、気づかない内に物品が購入されてしまう。

対策

重要な処理を行う際には、正規のルートからリクエストされたか確認する必要があります。確認方法としては、リクエストのパラメータとして第3者が知りえない秘密情報(トークン)が設定されているか判定する方法が一般的です。秘密情報にはセッションIDなどを利用します。

SQLインジェクション

概要

フォームで入力された値からSQLを作成するような場合、SQLインジェクションの対策をしていないと悪意あるSQLが実行されてしまいます。

対策

フォームなどから入力された値を利用してSQL文を組み立てる際、入力された値をエスケープしてSQL文が変更されないようにします。入力値に対してエスケープ関数を利用するやり方でもいいのですが、プリペアードステートメントを利用すればアプリ側でエスケープする必要がなくなるため、エスケープ漏れなどを防ぐことができます。

セッション固定攻撃

概要

セッション固定攻撃の対策をしないと、下記のようにセッションハイジャックされ、第3者による不正操作が実行可能になってしまいます。

1. ユーザAが罠サイト上から脆弱性サイトにアクセス(この時に、攻撃者がセッションIDを指定している)
2. ユーザAが脆弱性サイトにログイン(1で指定されたセッションIDが利用される)
3. 攻撃者は、1で指定したセッションIDを利用して脆弱性サイト上でユーザAの権限で不正操作を行う

対策

ログイン後、session_regenerate_id関数を実行してセッションIDを再発行することでセッション固定攻撃を防ぐことができます。