パスワードを忘れた? アカウント作成
733493 journal

pasasの日記: エスケープとセキュリティホール(その2)

日記 by pasas

なんだか最近このネタ多いな。

「SQL 文に値を渡すときにはエスケープしましょう」というのは、こちらでもちょこっと触れた通り。
でも、以下のように書いてもよくない。
(例によってサンプルは PHP。)

<?
$sql = "select * from table_name where uid = ".addslashes( $UID);

if( ( $result = pg_exec( $sql)) == false ) {
    die("pg_exec()");
    exit;
}
?>

ここでテーブル table_name の フィールド uid は int だとして、変数 $UID は URL に埋め込まれる形で送られてくるとする。
そして、通常の処理では UID は整数値しかとらないとする。

確かに $UID は addslashes でエスケープされているんだけど、
addslashes がエスケープするのはシングルクォーテーションや、\ などの記号だけで、その他の文字はエスケープしない。
とすると、ユーザが UID を以下のようにして URL に埋め込むと、

UID=1+%3B+delete+from+table_name+%3B

もう見てわかる通り、実行される SQL 文は次のようになる。

select * from table_name where uid = 1 ; delete from table_name ;

まぁ、これはテーブルの名前がわからないと実行できないんだけど、潜在的に重要な問題になっているということには注意。
「えー、だって一般ユーザはテーブル名までわからないよぉ」なんて言う方は、もう一度セキュリティについて考え直したほうがよいと思う。

というわけで結論。
入力された値を SQL 文に投入するときには、たとえその値が int だったとしても、クォーテーションで囲みましょう。
こんな感じ。

$sql = "select * from table_name where uid = '".addslashes( $UID)."' ";

または $UID が必ず int になるようなロジックを通すかだなぁ。

typodupeerror

一つのことを行い、またそれをうまくやるプログラムを書け -- Malcolm Douglas McIlroy

読み込み中...