英文では結構な頻度でシングルクオーテーションが出てきます。
しかし、『SQLインジェクションを考えれば、mysql_real_escape_stringなどでエスケープすることが望ましい。』とあります。
これはWHERE句に関しての話でしょうか?それとも格納するデータは全てエスケープして、表示するときに元に戻す方法があるのでしょうか?
セキュリティに関してネットを読み漁りながら対策を進めていますが、上記のことがイマイチ解らずにいます。
関係ないかもしれませんが、php文字コードはutf-8、MySQL文字コードutf-8、pcブラウザ表示文字コードutf-8、携帯ブラウザ表示コードshift_jisです。
どなたかアドバイスをお願いします。
まず正常ケースの場合ですが、WHERE句ではシングルクォーテーションをエスケープしないと文字列として認識しません。
MySQLではシングルクォーテーションを二重に '' とすればエスケープできますが、RDBMSによって違いがあるので、定石としてはRDBMSが用意するエスケープ関数(PHP+MySQLの場合はmysql_real_escape_string)を利用します。
次にSQLインジェクションのケースですが、シングルクォーテーションによるインジェクションで有名なケースは次のようなSQL文です。
SELECT * FROM table WHERE data1='{$key}1' and data2='{$key2}';
ここで
$key1 = ""; $key2 = "' or 'a'='a'; ";
を入力されると、
SELECT * FROM table WHERE data1='' and data2='' or 'a'='a'; '
となり、全レコードを抽出されてしまいます。
以上2点から、WHERE句の変数にシングルクォーテーションを含むと含まざるとに関わらず、mysql_real_escape_string関数でエスケープするのが定石となっています。
なお、これ以外にも様々なSQLインジェクションのケースが考えられます。
mysql_real_escape_string関数を通す前にユーザーが入力した値をチェックし、検索キーとして有り得ない値であればエラーを返すようにすべきです。ユーザーが入力した値をそのまま検索キーとして使ってはいけません。
「表示するとき」とはどういう意味でしょうか?
お知らせください。
>表示するとは、ブラウザに出力するときです。
2012/03/14 15:14:07エスケープ処理はRDBMS(MySQL)に対する処理なので、それによって結果が変わることはありません。RDBMSから受け取った値を「元に戻す」という操作は必要ありません。
>WHERE句以外なら、DBに格納するデータはエスケープしないでいいのでしょうか?
いいえ、違います。
WHERE句かどうかに関わらず、変数を使う箇所にはmysql_real_escape_string関数を適用するのが定石です。INSERT文でもエスケープ処理します。
次の公式マニュアルの「例」を参考にしてください。
http://php.net/manual/ja/function.mysql-real-escape-string.php
> エスケープ処理はRDBMS(MySQL)に対する処理なので、それによって結果が変わることはありません。
2012/03/14 18:29:52本当ですね。
以前、データが加工されたもの格納されたので、てっきりmysql_real_escape_stringの仕業だと思い込んでいました。
たぶん、postされたデータにhtmlspecialcharsあたりが掛っていたのかもしれません。
勘違いしていました。
ありがとうございます。