ユーザーが入力した場合の mysqli_real_escape_string の使用について
/
\
'
入力フィールドに?
それらは本当に有害ですか?
もしそうなら、彼らがする害は何ですか?
ユーザーが入力した場合の mysqli_real_escape_string の使用について
/
\
'
入力フィールドに?
それらは本当に有害ですか?
もしそうなら、彼らがする害は何ですか?
この文字のリスクは、'
入力内のリテラル引用符文字が、SQL 式内の引用符で囲まれた文字列を時期尚早に閉じる可能性があることです。例えば:
UPDATE Users SET password = '$pass' WHERE userid = $id
これは、 $input が文字列内で安全であることを前提としています。次のような URL を渡すと:
http://example.com/setpassword.php?id=1234&pass=xyzzy', admin='1
あなたのコードをだましてこれを行うことができます:
UPDATE Users SET password = 'xyzzy' AND admin='1' WHERE userid = 1234
自分自身に管理者権限を付与します。
mysqli_real_escape_string() のような関数の目的は、入力がコピーされる文字列を終了するためにリテラル引用符が使用されないようにすることで、それを防ぐことです。
したがって、私ができる最悪のことは、パスワードを長くて奇妙な文字列に設定することです。
UPDATE Users SET password = 'xyzzy\' AND admin=1' WHERE userid = 1234
入力変数を文字列に直接コピーするのではなく、パラメーター プレースホルダーを使用してクエリにバインドする方が便利なことがよくあります。
<?php
$stmt = $mysqli->prepare("UPDATE Users SET password = ? WHERE userid = ?");
$stmt->bind_param("si", $pass, $id);
$stmt->execute();
そうすれば、エスケープや不均衡な引用について心配する必要はありません。コードの見栄えが良くなり、読みやすくなり、デバッグと保守が容易になります。
唯一の欠点は、パラメーターがスカラー値の代わりになることだけです。それらを使用して、動的なテーブル名、列名、式、SQL キーワードなどを挿入することはできません。通常、SQL コードで文字列リテラル、日付リテラル、または数値リテラルを配置する場所にのみ使用してください。