0

パラメータ化されたクエリについては知っていますが、ユーザー入力をクリーンアップするためにこの方法を使用した古いサイトがいくつかあります。

<?
mysql_query( sprintf( 'SELECT col1 FROM table1 WHERE id = %d', $tainted ) );
?>

の周りに引用符がないことに注意してください%d$taintedそのようなクエリが予期しない結果をもたらす可能性がある値はありますか? 構文エラーを出すのは簡単ですが、私はそれについてあまり気にしません。

同様の UPDATE クエリと DELETE クエリにも同じ方法を使用しました。わざわざ戻って古いクエリをすべて修正する必要がありますか、それとも脆弱性はありませんか?

4

4 に答える 4

4

いいえ、脆弱性ではありません。

しかし、これは潜在的な脆弱性です: 一部の保守プログラマーが小さな変更を実行することを決定し、変数が汚染されている可能性があることを忘れた場合、または変数のデータ型が整数から文字列 (および指定子が%s) に変更された場合 -トラブルがあります。

そもそもそこに行かないほうがいいです (しかし、実際的な観点からは、このレガシー コードの防御を強化する価値があるかどうかも明らかではありません)。

于 2012-08-02T22:01:12.607 に答える
3

あなたの質問に答えるには、提示された方法で sprintf を使用すると、SQL インジェクションを回避する必要があります。これは、%d を介して 10 進数としてキャストされる非 int 値が単純に 0 の値を取るためです。

$ -> php -r "echo sprintf('update table where id = %d', 'drop databases');"
update table where id = 0

ただし、 PDO API、より具体的には、準備されたステートメントを使用するように説得しようとしなかったとしたら、私は気が進まないでしょう。mysqli API にもプリペアド ステートメントがあると思いますが、それらを使用したことはなく、PDO の準備、または Doctrine や Propel などの ORM のみを使用しました。

于 2012-08-02T22:05:19.057 に答える
1

入力としては十分に安全に見えますが、id 属性の場合に必要なパラメーターと入力が一致しない場合、ユーザーに詳細を提供できないため、ユーザー エクスペリエンスの観点からはお勧めできません。 .

于 2012-08-02T22:00:18.257 に答える
0

sprintf()変数が数値でない場合は変数を挿入しないため、理論的には脆弱ではないはずです。

ただし、それが正しいというわけではありません。コードを壊す可能性のあるエラーが発生する可能性があります。

これが脆弱であるかどうかに関係なく、mysql_xx()関数から完全に切り替えることを強くお勧めします。

古い MySQL ライブラリは廃止されており ( PHP マニュアル ページの注意事項を参照)、PDO またはmysqli_xxライブラリに切り替えることをお勧めします。

sprintf()PDO と MySQL の両方に、Prepared Queries と呼ばれる機能が付属しています。これは、ここで達成しようとしていることを正確に実行し、この種のものよりもはるかに優れたソリューションです。SQL のすべての変数もエスケープする必要がなくなります。

それが役立つことを願っています。

于 2012-08-03T20:13:37.480 に答える