PHP覚え書きブログ

【2012年02月06日】

今回はSQLインジェクション対策の数値項目の場合。
数値型項目に対してなんのチェック行っていないと、簡単にインジェクション攻撃を許す。

例えばある通販サイトで商品検索として価格指定のボックスがあるとする。
価格がいくら以下のもののみ表示、みたいな。
これは、

<?php

$sql = "
    SELECT
        * 
    FROM
        m_product
    WHERE
        price <= " . $maxPrice
    ;

?>

という感じのSQLになり、通常であれば「3000」と入力すればpriceが3000以下のものが抽出される仕組みだが、
ここに「3000;DELETE FROM m_product」って入れられたら、

SELECT
    * 
FROM
    m_product
WHERE
    price <= 3000;DELETE FROM m_product

こんな事をやられたら目も当てられない。
一瞬にして商品マスタは真っ白である。

この場合、数値なのでシングルクォートも存在しない。なのでエスケープしても同じなのである。
この例の問題はエスケープ以前の問題。
数値項目に対して文字列の入力を許してしまっている事がいけないのである。
単純に数値項目にたいしてはis_numeric関数などによって数値チェックを行えば問題ない。

また、もう一つの方法として、数値型にキャストすると言うのも手。
PHPの特性上、文字列を数値にキャストすると、数字以外はそぎ落とされる。
「3000;DELETE FROM m_product」という値が入った変数を数値型に変換すると「3000」になる。
しかしこれだけではあまりに乱暴なので、
事前の数値チェックは必ず行い、念のため、最終的に数値型へキャストすると言うのがよいだろう。
このクセを付けておけば、万一数値チェックを忘れていたとしても、とりあえずは助かる。