PHPのエスケープ処理に関して、ここにある記事のがるさんの説明がとても分かりやすいものでした。セキュリティ的にも重要そうなので、メモしておきます。
ここから引用
サンプルコードのママではNGなので、ちと簡単に解説を。まず、少し書き直してみます。合わせて変数名を少し替えます。
// 例えば $raw_data_name = $_POST[name]; $html_escaped_name = htmlspecialchars($raw_data_name, ENT_QUOTES); $sql_escaped_name = mysql_real_escape_string($raw_data_name); // ポストで受け取った値を表示させたい場合 echo $html_escaped_name; // ポストで受け取った値を検索したい場合 $sql = "SELECT * FROM table WHERE name LIKE '%$sql_escaped_name%';
まず。raw_data_nameは「ユーザから投げられたパラメタそのもの」で、一部では「汚染データ」とも呼びます。これを直接使うにはいろいろな意味でNGです。 HTMLに出力するときは、htmlspecialcharsなどで適切にエスケープ処理されたものを使いましょう。
また、SQL用にエスケープするときは「ユーザから投げられたパラメタそのもの」を適切なエスケープ関数( お使いになってる mysql_real_escape_string など )で処理しましょう。
元のコードだと「HTML用エスケープされたデータをさらにSQL用にエスケープ」しているのでよろしくないです。
また、本質的には「使う直前にエスケープ」が基本なので。
// 例えば $raw_data_name = $_POST[name]; // ポストで受け取った値を表示させたい場合 echo htmlspecialchars($raw_data_name, ENT_QUOTES, "UTF-8"); // ポストで受け取った値を検索したい場合 $sql = "SELECT * FROM table WHERE name LIKE '%" . mysql_real_escape_string($raw_data_name) . "%'";
と書いた方がより間違えにくいかもしれません。
まとめると…
- エスケープ処理は、画面(ブラウザ)に表示する直前とMySQLに問い合わせる直前に行う。
- 画面(ブラウザ)に表示する際は、htmlspecialcharsを用いてエスケープを行う。記述は、htmlspecialchars($str, ENT_QUOTES, UTF-8); 。
- MySQLに問い合わせる(追加・検索・更新・削除)時には、mysql_real_escape_stringを用いてエスケープを行う。例えば、$sql = SELECT * FROM table WHERE name LIKE ‘% . mysql_real_escape_string($raw_data_name) . %’;
- これらの各処理はその値を使う直前にエスケープすることが大前提である。