mysql_real_escape_string
SQL 文中で用いる文字列の特殊文字をエスケープする
警告
この拡張モジュールは PHP 5.5.0 で非推奨になり、PHP 7.0.0 で削除されました。
MySQLi あるいは
PDO_MySQL を使うべきです。詳細な情報は
MySQL: API の選択 を参照ください。
この関数の代替として、これらが使えます。
- mysqli_real_escape_string
- PDO::quote
説明
string mysql_real_escape_string(string $unescaped_string
, resource $link_identifier
= NULL)
mysql_real_escape_string は、MySQL のライブラリ関数
mysql_real_escape_string をコールしています。
これは以下の文字について先頭にバックスラッシュを付加します。
\x00
, \n
,
\r
, \
, '
,
"
そして \x1a
.
データの安全性を確保するため、MySQL へクエリを送信する場合には
(わずかな例外を除いて)常にこの関数を用いなければなりません。
警告
セキュリティ: デフォルトの文字セット
サーバーレベルで設定するなり API 関数
mysql_set_charset を使うなりして、
文字セットを明示しておく必要があります。この文字セットが
mysql_real_escape_string
に影響を及ぼします。詳細は
文字セットの概念
を参照ください。
パラメータ
-
unescaped_string
-
エスケープされる文字列。
-
link_identifier
-
MySQL 接続。指定されない場合、mysql_connect により直近にオープンされたリンクが指定されたと仮定されます。そのようなリンクがない場合、引数を指定せずに mysql_connect がコールした時と同様にリンクを確立します。リンクが見付からない、または、確立できない場合、E_WARNING
レベルのエラーが生成されます。
戻り値
成功した場合にエスケープ後の文字列、失敗した場合に false
を返します。
エラー / 例外
MySQL 接続が存在しない状態でこの関数を実行すると、
E_WARNING
レベルのエラーが発生します。
この関数は、MySQL 接続が確立した状態でのみ実行するようにしましょう。
例
例1 単純な mysql_real_escape_string の例
<?php
// 接続
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OR die(mysql_error());
// クエリ
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
?>
例2 mysql_real_escape_string には接続が必須であることを示す例
この例では、MySQL 接続が存在しない状態でこの関数を実行したときにどうなるかを示します。
<?php
// まだ MySQL に接続していません
$lastname = "O'Reilly";
$_lastname = mysql_real_escape_string($lastname);
$query = "SELECT * FROM actors WHERE last_name = '$_lastname'";
var_dump($_lastname);
var_dump($query);
?>
Warning: mysql_real_escape_string(): No such file or directory in /this/test/script.php on line 5
Warning: mysql_real_escape_string(): A link to the server could not be established in /this/test/script.php on line 5
bool(false)
string(41) "SELECT * FROM actors WHERE last_name = ''"
例3 SQL インジェクション攻撃の例
<?php
// $_POST['password'] をチェックしなければ、このような例でユーザーに望みどおりの情報を取得されてしまう
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";
// データベース上のユーザーに一致するかどうかを調べる
$query = "SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'";
mysql_query($query);
// MySQL に送信されたクエリは、
echo $query;
?>
SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''
これでは、パスワードを知らなくても誰でもログインできてしまいます。
注意
注意:
mysql_real_escape_string を利用する前に、MySQL
接続が確立されている必要があります。もし存在しなければ、
E_WARNING
レベルのエラーが生成され、false
が返されます。link_identifier
が指定されなかった場合は、
直近の MySQL 接続が用いられます。
注意:
この関数を用いてデータをエスケープしなければ、クエリは
SQL インジェクション攻撃
に対しての脆弱性を持ったものになります。
注意:
mysql_real_escape_string は
%
や _
をエスケープしません。
MySQL では、これらの文字を LIKE
, GRANT
,
または REVOKE
とともに用いることで、
ワイルドカードを表現します。
参考
- mysql_set_charset
- mysql_client_encoding