SQLインジェクション脆弱性を狙った大規模な攻撃が繰り返し行われ,
SQLインジェクション脆弱性が無くならない理由には以下のようなものが考えられます。
- 過去のコードやアプリケーションの再利用
- 基本的なセキュリティ知識不足
- セキュアコーディングプラクティスの未実施
- コード監査の不在
SQLインジェクション脆弱性の発見だけを目的にコード監査を行うことはあまりありませんが,
本題に入る前にSQLインジェクションの基礎知識クイズをしてみてください。いくつの質問に自信を持って答えられるでしょうか? すべて自信がある方はこの記事を読まなくても大丈夫な方です。
SQLインジェクションクイズ
SQLインジェクションに対する知識をクイズとしてお聞きます。○か×かで答え,
- SQLインジェクションはエスケープ処理を確実にしていれば大丈夫?
- プリペアードクエリを利用していれば大丈夫?
- SQLインジェクションはデータベース構造を知らないと攻撃が難しい?
- SQLインジェクションはWebアプリケーションファイアーウォールで防御できる?
- 文字エンコーディングベースのSQLインジェクションは文字エンコーディングが正しければ行えない?
SQLインジェクションを目的としたコードのチェック
PHPアプリの場合,
- 文字エンコーディングが正しいか検証し,
文字エンコーディング関連の処理を厳格に行う - クエリを生成する場合に
「すべて」 のパラメータを文字列として扱いエスケープ処理してクエリを生成する - プリペアードクエリ生成の際に,
プリペアード文にパラメータを入れない - テーブル名,
フィールド名をパラメータで指定する場合, ホワイトリスト方式で確認する
コードチェックはこれらのベストプラクティスが実践されているかチェックすることが目的となります。これらのベストプラクティスを守っていなくてもSQLインジェクションが不可能なコードを記述可能ですが,
SQLインジェクション脆弱性チェックのポイント
チェックポイント:すべての入力がmb_
壊れた文字エンコーディングを利用したSQLインジェクションを防ぐためには文字エンコーディングが正しいか確認することが最も確実です。SQLインジェクション以外の攻撃にも壊れた文字エンコーディングが利用されるので,
$_POST,
チェックポイント:文字列のエスケープにデータベースAPI関数を利用し,
文字列のエスケープ処理を常に正しく行うには,
チェックポイント:すべてのパラメータをエスケープしているか?
文字列のエスケープは多少のオーバーヘッドが必要です。すべてのパラメータをエスケープするのは無駄に思えるかもしれませんが,