MySQL5とphp5.2.2でのシングルクオーテーションの扱いについての質問です。

英文では結構な頻度でシングルクオーテーションが出てきます。
しかし、『SQLインジェクションを考えれば、mysql_real_escape_stringなどでエスケープすることが望ましい。』とあります。
これはWHERE句に関しての話でしょうか?それとも格納するデータは全てエスケープして、表示するときに元に戻す方法があるのでしょうか?

セキュリティに関してネットを読み漁りながら対策を進めていますが、上記のことがイマイチ解らずにいます。
関係ないかもしれませんが、php文字コードはutf-8、MySQL文字コードutf-8、pcブラウザ表示文字コードutf-8、携帯ブラウザ表示コードshift_jisです。
どなたかアドバイスをお願いします。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2012/03/14 18:33:19
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答1件)

id:oil999 No.1

回答回数1728ベストアンサー獲得回数320

ポイント100pt

まず正常ケースの場合ですが、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関数を通す前にユーザーが入力した値をチェックし、検索キーとして有り得ない値であればエラーを返すようにすべきです。ユーザーが入力した値をそのまま検索キーとして使ってはいけません。

>表示するときに元に戻す方法があるのでしょうか?

「表示するとき」とはどういう意味でしょうか?
お知らせください。

他1件のコメントを見る
id:oil999

>表示するとは、ブラウザに出力するときです。
エスケープ処理はRDBMS(MySQL)に対する処理なので、それによって結果が変わることはありません。RDBMSから受け取った値を「元に戻す」という操作は必要ありません。

>WHERE句以外なら、DBに格納するデータはエスケープしないでいいのでしょうか?
いいえ、違います。
WHERE句かどうかに関わらず、変数を使う箇所にはmysql_real_escape_string関数を適用するのが定石です。INSERT文でもエスケープ処理します。
次の公式マニュアルの「例」を参考にしてください。
http://php.net/manual/ja/function.mysql-real-escape-string.php

2012/03/14 15:14:07
id:seadwell

> エスケープ処理はRDBMS(MySQL)に対する処理なので、それによって結果が変わることはありません。
本当ですね。
以前、データが加工されたもの格納されたので、てっきりmysql_real_escape_stringの仕業だと思い込んでいました。
たぶん、postされたデータにhtmlspecialcharsあたりが掛っていたのかもしれません。
勘違いしていました。
ありがとうございます。

2012/03/14 18:29:52
  • id:JULY
    質問の内容から少しそれますが、SQL インジェクション対策でエスケープ処理をするぐらいなら、プレースホルダを使った方が良いです。

    「安全なウェブサイトの作り方」- IPA(PDF)
    http://www.ipa.go.jp/security/vuln/documents/website_security.pdf

    上記資料の 65 ページ(PDF 上のページとしては 67 ページ)の「修正例 1」に、php の mysqli を使った具体例が出ています。
  • id:seadwell
    コメントありがとうございます。
    興味深い資料をありがとうございます。
    早速印刷して読んでみます。
    ありがとうございました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません