とりあえずの備忘録

備忘録(びぼうろく)。主にパソコンやインターネットに関する様々なことを個人的にメモしています。

MySQL mysql_real_escape_stringでSQLインジェクションを防ぐ

SQLインジェクションへのセキュリティ対策で調べたときのメモです。

サーバーの環境は、PHPとMySQL。

SQLインジェクションとは?

SQLインジェクションとは、データベースと連動したWebサイトで、データベースへの問い合わせや操作を行うプログラムにパラメータとしてSQL文の断片を与えることにより、データベースを改ざんしたり不正に情報を入手する攻撃。また、そのような攻撃を許してしまうプログラムの脆弱性のこと。

SQLインジェクションとは|SQL injection - 意味/定義 : IT用語辞典

SQLインジェクションの例

入力データに名前を入れて、その名前の人の情報があれば取得するSQL文があります。

SELECT * FROM users WHERE name = '(入力データ)';

この入力データに、例えば「' OR 't' = 't」を指定されると、

SELECT * FROM users WHERE name = '' OR 't' = 't';

のようなSQL文が出来上がります。
すると、WHERE句の条件は「nameが空っぽ、もしくは、't' = 't'」となり、条件が常に成立してusersテーブル全ての情報が取り出せてしまいます。いわゆる個人情報流出です。

mysql_real_escape_stringでSQLインジェクションを防ぐ

このようなことが起きないように入力データをエスケープ処理します。そして、PHPにはそのための機能があらかじめ用意されていて、mysql_real_escape_string関数を使います。

入力データがフォームから送られてくる場合に、SQLインジェクションを防ぐ

<?php
//マジッククオートがONの場合、自動的にaddslashesによるエスケープ処理がされるので元に戻す
if(get_magic_quotes_gpc()) {
  $name = stripslashes($_POST['name']);
} else {
  $name = $_POST['name'];
}

//入力データをエスケープ処理して安全な入力データに加工する
$name2 = mysql_real_escape_string($name);

//SQL文を作成
$sql = "SELECT * FROM users WHERE name = '" . $name2 . "'";
?>

このようなエスケープ処理をしないことは、SQLインジェクションに対する脆弱性を残す結果になります。