- ベストアンサー
SQLインジェンクション対策法をおしえてください。
' OR 1=1のように外部から認識されていない値をSQLクエリにする前に一度確かめる機能を加えたいのですがなかなかうまくいきません。 外部から入力されたシングルクォートをエスケープするにはどうしたらよいのでしょうか?(ソースなどあると助かります。) また、そのほかに有効な対策法などありましたら教えていただけると幸いです。 どうぞよろしくお願いいたします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
補足質問の回答です。 $param = ctype_alnum($_POST['id_posted']) ? $_POST['id_posted'] : some_error_handling(); また、恥ずかしながら私はPHPに関しては初心者でsome_error_handling()を初めて目にします。これはいったいどのような働きを行うのでしょうか?よろしくお願いいたします。 混乱させたようで、申し訳ありません。 some_error_handling()は 何かエラー処理を実行してくださいという意味ですので、デフォルトの関数でもありませんし、拡張モジュールの関数にもありません。 ctype_alnumで書くとしたら 例えば、HTMLのフォームに <input type="text" name="user_name" value="" /> のようにあった場合、受け取り側のPHPファイルでは <?php /* 初期化 */ $username = ""; /* 配列をPOSTされた場合の処理 */ $_POST['user_name'] = (string)$_POST['user_name']; if(ctype_alnum($_POST['user_name'])===true){ $username = $_POST['user_name']; } else { /* ここでエラー処理をする、 */ /* 例えば、 再度入力画面に戻る、 *header()でリダイレクトさせる、または *include(入力画面用.php)など 又は、処理を中断する、 exit(); 又は、デフォルトの値を $usernameに代入するなどの処理を 書けばいいと思います。 (ユーザー名やパスワードの場合はデフォルト値を 入れることはないと思いますが・・・・) */ } ?>
その他の回答 (5)
- alioth
- ベストアンサー率48% (13/27)
DBはMySQLなんですね。 mysql_escape_string は正しく使えばもちろん効果はありますが、1つの漏れもなく、ただしく使う必要があります。 ですから、PEAR をおすすめしています。 参考URLに挙げたサイトなど、PEARについて調べましたか? PEARに限らず、プレースホルダのような機能を使わずに、SQLインジェクションを防ぐことは、かなり慣れたプログラマでも困難なことです。
お礼
回答ありがとうございました。 すいません、DBはMySQLです。 PEARは以前から興味がありいじっていたのですがSQL Injection対策に有効とは知りませんでした。 ありがとうございました。
- alioth
- ベストアンサー率48% (13/27)
失礼ながら、まだPHP、データベース共に知識が深くないように見受けられます。 それなら、PEARのような既に実績のあるライブラリを使うことをおすすめします。 PEARのプレースホルダーの機能を使えば $query = "SELECT * FROM ACCOUNT WHERE ID = ? AND PASS = ?"; $result = $con->getAll($query, array($UID,$PASS)); のように、エスケープの処理を一切考えずにクエリを書くことができ、使用するDBに併せて、PEARが適切にサニタイジングしてくれます。 すべてのクエリにプレースホルダを使うと決めてプログラミングするとSQLインジェクションについては、回避できます。
お礼
Pearですか、挑戦してみたいと思います。 ありがとうございました。
補足
関数のmysql_escape_stringとはSQL Injection に有効なのでしょうか?
- veax
- ベストアンサー率75% (3/4)
エスケープでは対処しきれない場合があります。 個々のフィールドに対するctypeやcastを使う方法もいいかもしれません。 例えばIDカラムには通常数字が入り、 ポストされる文字も数値を期待しているのであれば $param = ctype_digit($_POST['id_posted']) ? $_POST['id_posted'] : some_error_handling(); 又は、 $param = (int)$_POST['id_posted'] などでも出来ると思います、 文字列ならば、単純に 使用不可能の文字を発見した時点で もう一度入力画面に戻るかデフォルトのクエリーを 発行するのがいいのでは?この場合は"'"
補足
回答ありがとうございます。 $param = ctype_digit($_POST['id_posted']) ? $_POST['id_posted'] : some_error_handling();と書いていただきましたが、もし渡される値が英数字の場合はどうなるのでしょうか? 私なりに調べ考えてみた結果以下のようになりました。 $param = ctype_alnum($_POST['id_posted']) ? $_POST['id_posted'] : some_error_handling(); また、恥ずかしながら私はPHPに関しては初心者でsome_error_handling()を初めて目にします。これはいったいどのような働きを行うのでしょうか?よろしくお願いいたします。
- hegemonism
- ベストアンサー率53% (37/69)
参考URLにいろいろと議論されていますので、 覗いてみてはいかがでしょう。 あと、以下の記事が参考になるかと・・・ http://www.atmarkit.co.jp/fsecurity/special/30xss/xss01.html
- Bonjin
- ベストアンサー率43% (418/971)
通常は\がエスケープ文字になりますが、DBMSによって異なる場合があります。使っているDBMSのエスケープ文字について調べてみてください。
補足
回答ありがとうございます。 \がエスケープ文字の場合、' OR 1=1では攻撃できませんが、\' OR 1=1 では攻撃されてしまいます。 どうすればいいのでしょうか?
お礼
回答ありがとうございました。