人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHP & SQL Injection対策

$sql = sprintf("SELECT * FROM `hatenainfo` WHERE name = '%s'", mysql_real_escape_string($name));

$sql = "SELECT * FROM `hatenainfo` WHERE name = 'mysql_real_escape_string($name)'";

は何が異なるのでしょうか?
どちらの方が安全ですか?

また、Pear DBやAdodbを使用する際、単に

$db->EXECUTE("SELECT * FROM `hatenainfo` WHERE name = ?", array($_POST['name']));
とやっても安全でしょうか?

*今回はSQLインジェクションのみお願いいたします。表示する際は問題なくHTMLをエスケープしています。

よろしくお願いいたします。

●質問者: esecua
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:dB HTML name Pear PHP
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● pahoo
●27ポイント

選択結果が異なります。

$sql = sprintf("SELECT * FROM `hatenainfo` WHERE name = '%s'", mysql_real_escape_string($name));

テーブル hatenainfo の中から、カラム name と変数 $name を mysql_real_escape_string でエスケープした結果が合致するレコードを選択します。

$sql = "SELECT * FROM `hatenainfo` WHERE name = 'mysql_real_escape_string($name)'";

テーブル hatenainfo の中から、カラム name と文字列 'mysql_real_escape_string($name)' が合致するレコードを選択します。


ご質問の SQL 文は勘違いだと思うのですが、PHP の mysql_real_escape_string は MySQL の C API "mysql_real_escape_string" をインターフェースするだけなので、PHP 側でエスケープしても、MySQL 側でエスケープしても結果は同じです。

ただし、PHPに限らない一般論として、アプリケーション側(言語側)で DBMS が用意するエスケープ手段を適用するのが定石となっています。


単に

$db->EXECUTE("SELECT * FROM `hatenainfo` WHERE name = ?", array($_POST['name']));

とやっても安全でしょうか?

いちおう安全ということになっています。

ただ、個人的には、自力でSQLインジェクション対策のコードを書いた方が良いと考えています。Pead::DBに脆弱性があったり、新しいインジェクションが発見されたりした場合、即座に対応できませんので。

◎質問者からの返答

なるほど。参考になります。

ところで私は

$sql = sprintf("SELECT * FROM `hatenainfo` WHERE name = '%s'", mysql_real_escape_string($name));

の方法を使用しいているのですが、現在知られているSQLインジェクションには問題なく対応できているのでしょうか?


2 ● pahoo
●27ポイント

mysql_real_escape_string 関数だけで既知の SQL インジェクションに対応できるかというと、そうではありません。


有名な例としては、マルチバイトコード問題があります。

もし内部コードをシフトJISで処理しているとすると、$name = ""\x97' or 1=1" を mysql_real_escape_string 関数 に通すと、"予' or 1=1" となってしまいます。シングルクォーテーションがエスケープされないのです。

結果的に、SQL文がエラーを起こすか、場合によってはインジェクションされる可能性があります。


もっとも、これは SQLインジェクションの問題ではなく、マルチバイトコードに対する設計の甘さから起きる問題です。

SQLインジェクション対策に加え、マルチバイトコード対策、入力値バリデーションチェックをきちんと行っていれば、DBへの攻撃は避けられるでしょう。


参考サイト


3 ● sphire
●26ポイント

SQLインジェクション対策という意味では、mysql_real_escape_string() を用いることでSQLの特殊文字がエスケープされるので、いずれにしても安全である、ということになります。

Pear::DBのプリペアドステートメントなんかでも、MySQLドライバのコードを追えば分かりますが、結局 execute → executeEmulateQuery → quoteSmart → escapeSimple → mysql_real_escape_string と呼び出していますので、同じですね。

◎質問者からの返答

なるほど、参考になります。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ