dポイントプレゼントキャンペーン実施中!

' OR 1=1のように外部から認識されていない値をSQLクエリにする前に一度確かめる機能を加えたいのですがなかなかうまくいきません。

外部から入力されたシングルクォートをエスケープするにはどうしたらよいのでしょうか?(ソースなどあると助かります。)

また、そのほかに有効な対策法などありましたら教えていただけると幸いです。

どうぞよろしくお願いいたします。

A 回答 (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に代入するなどの処理を
書けばいいと思います。
(ユーザー名やパスワードの場合はデフォルト値を
入れることはないと思いますが・・・・)
*/
}

?>
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

お礼日時:2005/12/29 02:10

DBはMySQLなんですね。


mysql_escape_string は正しく使えばもちろん効果はありますが、1つの漏れもなく、ただしく使う必要があります。

ですから、PEAR をおすすめしています。
参考URLに挙げたサイトなど、PEARについて調べましたか?

PEARに限らず、プレースホルダのような機能を使わずに、SQLインジェクションを防ぐことは、かなり慣れたプログラマでも困難なことです。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

すいません、DBはMySQLです。

PEARは以前から興味がありいじっていたのですがSQL Injection対策に有効とは知りませんでした。

ありがとうございました。

お礼日時:2005/12/31 00:02

失礼ながら、まだPHP、データベース共に知識が深くないように見受けられます。


それなら、PEARのような既に実績のあるライブラリを使うことをおすすめします。

PEARのプレースホルダーの機能を使えば
$query = "SELECT * FROM ACCOUNT WHERE ID = ? AND PASS = ?";
$result = $con->getAll($query, array($UID,$PASS));
のように、エスケープの処理を一切考えずにクエリを書くことができ、使用するDBに併せて、PEARが適切にサニタイジングしてくれます。

すべてのクエリにプレースホルダを使うと決めてプログラミングするとSQLインジェクションについては、回避できます。

参考URL:http://kamakura.cool.ne.jp/oppama/oswa/phppeardb …

この回答への補足

関数のmysql_escape_stringとはSQL Injection に有効なのでしょうか?

補足日時:2005/12/30 13:20
    • good
    • 0
この回答へのお礼

Pearですか、挑戦してみたいと思います。

ありがとうございました。

お礼日時:2005/12/29 02:10

エスケープでは対処しきれない場合があります。


個々のフィールドに対する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()を初めて目にします。これはいったいどのような働きを行うのでしょうか?よろしくお願いいたします。

補足日時:2005/12/24 15:23
    • good
    • 0

参考URLにいろいろと議論されていますので、


覗いてみてはいかがでしょう。
あと、以下の記事が参考になるかと・・・
http://www.atmarkit.co.jp/fsecurity/special/30xs …

参考URL:http://vsug.jp/tabid/63/forumid/56/postid/537/vi …
    • good
    • 0

通常は\がエスケープ文字になりますが、DBMSによって異なる場合があります。

使っているDBMSのエスケープ文字について調べてみてください。

この回答への補足

回答ありがとうございます。

\がエスケープ文字の場合、' OR 1=1では攻撃できませんが、\' OR 1=1 では攻撃されてしまいます。

どうすればいいのでしょうか?

補足日時:2005/12/23 12:58
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!