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

現在、PHPでのセキュリティ対策の一環として、SQLインジェンクション対応のためのユーザ入力値をチェックするための関数を検討しています。
以下のサイトなどを参考に、以下のようなサンプルコードを検討してみました。

特筆すべき点は、PHPのマジッククォートがONになっているかどうかのチェックを最初に入れ、余分に不正コードをエスケープしないようにしたことでしょうか。

あまりセキュリティについて詳しくないので、有識者の方の見解を伺いたく投稿いたしました。その他付け加えるべきチェックなどありましたら、ご意見賜りたく存じます。

(参考にしたサイト)
http://jp.php.net/manual/ja/security.database.sq …



(サンプルコード)
function str_check($value)

{
// strip slashes
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}

// quote except numbers
if (!is_numeric($value)) {
$value = "'" . mysql_real_escape_string($value) . "'";
}
return $value;
}

(使用例)
$query = sprintf("SELECT * FROM users WHERE user=%s AND password=%s",
str_chec($_POST['username']),
str_chec($_POST['password']));

mysql_query($query);

A 回答 (2件)

インジェクション処理にはやりすぎと言うものはありません。


どんなにチェックしても抜けるときは抜けますので
「余分にエスケープしない」など考える余裕はないはずです。

以下注意すると方針がきめやすくなると思います

・基本はエスケープしづらいshiftjisは排除する。
・各SQL用に用意されたエスケープ関数は積極的に使う
 例:mysql_real_escape_string()とかpg_escape_string()
・怪しいデータがとんできたときはとにかく早期にはじく
    • good
    • 0
この回答へのお礼

ご指摘ありがとうございました。いただいたコメントを踏まえ、もう少し考えてみます。

お礼日時:2008/07/28 09:33

無識者です.



処理の定義域と値域を考えることが大切です.
処理が何を入力として取り,何を出力するかですね.
str_checで考えれば,定義域はユーザIDか,パスワードですが
単に何かの文字列というだけで何が入っているかや長さは不明です.
JavaScriptで入力を制限していたとしても,攻撃者の作ったフォームから送信されたら終わりですね.
ですから,値域はstripslashesでバックスラッシュが取り除かれ
mysql_real_escape_stringでエスケープ関連の文字が取り除かれ?た長さ不明の文字列です.
英数字以外に漢字やひらがなが混じっているかもしれません.
次にsprintfですが,入力が何が入っているともわからない長さ不明の(いちおう危なそうな文字は除いた)文字列が定義域です.
となると,値域はSQL文に内容不明の文字列が含まれる長さ不明の文字列です.

という風に,考えていくとあなたがSQL文に与えるクエリは内容不明,長さ不明の危なっかしい文字列だと言うことになります.
ユーザ名とパスの文字種別と長さを確認するだけでだいぶよくなります.

またこの場合は処理の大半が外部の関数に丸投げされていますが
使っている関数の入出力,それが本当に信用できるかも確認した方が良いです.
古いバージョンなら既知の脆弱性がある可能性がありますし,
新しい脆弱性が見つかる可能性があるのでこまめに確認が必要です.

と,素人が何となく思い浮かぶくらいでこれくらいありますね.
間違った内容があるかもしれませんが,プロならもっと考慮すべき事項があるかもしれません.
    • good
    • 0
この回答へのお礼

詳細なコメントありがとうございました。
たしかに、セキュリティ対策って対策を施してもまた破られたり、イタチごっこだったりすることもあるので、難しいですよね。いろいろな観点から、もう少し考えをめぐらせてみます。

お礼日時:2008/07/23 07:01

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