PHP覚え書きブログ

【2012年02月06日】

サイト攻撃の手法の一つにSQLインジェクションと呼ばれるものがある。
データベースを使用したWebアプリで、不正なSQL文を故意に実行させることによってデータを改ざんしたり、不正認証を行ったりする方法。

どうやってこれを実現させるか。

例えばユーザーIDとパスワードを入力するログイン画面があるとする。
アプリでは最終的にデータベースのユーザーテーブルに対して例えば以下のようなSQLでもって認証チェックを行う。

<?php

$sql = "
    SELECT
        * 
    FROM
        m_user
    WHERE
        user_id = '" . $userId . "' AND
        password = '" . $password . "'
    ";

?>

クエリ結果が存在すれば認証という具合。
で、例えばパスワードに対して「' OR 'baka' = 'baka」
と入力したらどうなるか。
こうなります。

SELECT
    * 
FROM
    m_user
WHERE
    user_id = 'aaa' AND
    password = '' OR 'baka' = 'baka'

このSELECT文のWHERE区は常に真となってしまう。
つまりこうすればパスワードなんか関係なしに誰でもログインできてしまうわけである。

もしフォームの入力値をそのままSQL文に突っ込んでいたらすぐにでも対策しましょう。

具体的には、まず入力値に対してエスケープ処理を行う。
上記の例のような攻撃は、SQL文にとっては特別な意味を持つシングルクォートを含めることが可能な為に起こる。
なのでシングルクォートを一つの文字として処理するのである。
つまりエスケープ。
これを行う関数がaddslashes。といいたいところだが、実はこれは現在は推奨されていない。
addslashesのエスケープは「'」「"」「\」にエスケープ文字である「\」を付加するというもの。
しかし実際にはデータベース側で推奨されているエスケープの仕方というものがあり、
それに従ったエスケープを行うべきなのである。
で、MySQLの場合であればmysqli_real_escape_string、
PostgreSQLの場合であればpg_escape_stringという関数が用意されているのでこれらを使用する。

以上は文字列型項目の場合の話。
数値の場合については後日。