4

この質問に答える予定がある場合は編集してください。少なくとも読んでください。単にタイトルを読んでから、Google の「SQL インジェクション php」を読んで、結果を回答として貼り付けないでください。

まず、SQL インジェクションを防ぐための最善の方法については、多くのリソースが利用できることをよく知っていますが、私の質問は、特に、ほんの少しの努力で十分かどうかについてです。

私が契約している組織は最近、以前の請負業者によって開発されたパートナーの (PHP) Web サイトに重大なセキュリティ上の問題があることが判明したと言われました (私の個人的なお気に入りは、URL に「Emergency」という文字列を使用することで、任意の場所への認証されていないアクセスを取得できることです)。サイト内のページ...)

PHP サイトのセキュリティを確認し、主要な問題を指摘するように依頼されました。このサイトでの以前の経験から、コーディングの標準が本当にひどいものであることを知っています (たとえば、約 5% のバリエーションでページ全体に大量のコードが複製されている、何百もの未使用の変数、ブール値の代わりに $var = "yes" が記述されている、SQL ステートメントが記述されているなど)。デフォルトでは安全でない (一部のページはユーザーの認証を忘れている) など)。このサイトを見直すと、世界には自分たちを開発者と呼ぶ真の馬鹿がいるということを痛感させられます。

これらのコード品質の問題のため、重大または半重大なセキュリティ問題のみを強調したいと思います。サイトのすべての問題に注意すると、レビューには数週間かかります。

私は SQL インジェクションの専門家ではありませんが、他の種類のステートメントを挿入する前に、既存のクエリの引用符で囲まれた文字列を閉じることができなければならないことを理解しています。では、次のコード行で十分でしょうか?

"'".str_replace("'","''",$_POST['var_name'])."'"

このシナリオで $_POST['var_name'] を介した SQL インジェクションが可能かどうかだけで、コードの改善または変更に関する提案には興味がありません。PHP に慣れていない場合str_replace 、最初のインスタンスだけでなく、最初の引数のすべてのインスタンスを 2 番目の引数に置き換えます。

どんな入力でも大歓迎です。

4

5 に答える 5

8

いいえ、正直に言って、あなたが声明を準備していないなら、あなたは傷ついた世界を求めています.

引用符を引用符でエスケープしたからといって、自分自身を保護していません。これについて考えます:

ユーザーがあなたに送信するもの:username'; drop database foo;

あなたはそれをエスケープしますusername''; drop database foo;

しかし!ユーザーが行う場合:username\'; drop database foo;

あなたは困るでしょう。あなたはこれを解決しますusername\''; drop database foo;

ユーザーが配置した引用がエスケープされ、引用がユーザー名フィールドを終了したことを意味します。その後、ドロップが実行されます。これは非常に安全ではありません。

ステートメントを準備するか、またはこれらのエスケープ特殊文字quoteなどのコマンドを適用する必要があります。PDO::quotemysqli_real_escape_string

于 2012-07-22T01:39:36.307 に答える
1

unsafe_variable で特殊文字をエスケープするか、パラメーター化されたクエリを使用するという 2 つのオプションがあります。

$safe_variable = mysql_real_escape_string($_POST["user-input"]);


$mysqli = new mysqli("server", "username", "password", "database_name");    
$unsafe_variable = $_POST["user-input"];
$stmt = $mysqli->prepare("INSERT INTO table (column) VALUES (?)");

どちらも SQL インジェクションから保護します。パラメーター化されたクエリはより良い方法と考えられていますが、変数内の文字をエスケープすると変更が少なくて済みます。

于 2012-07-22T01:07:12.353 に答える
0

あなたの質問に答えるには:いいえ、引用符を削除するだけではSQLインジェクションを防ぐのに十分ではありません。

例えば、

"SELECT * FROM user_table WHERE userid=$userid AND password=$password"

$password「ごみOR1」などが含まれていると、ひどくうまくいかない可能性があります。したがって、不適切な形式のクエリがある場合は、引用符を削除しても効果はありません。

于 2012-07-22T01:27:03.297 に答える
0

これは、データベース サーバーとその構成によって異なります。

2 倍'にすること''は、文字列リテラル コンテンツをエスケープする ANSI 標準の方法であり、十分なはずです。

ただし、MySQL または 9.1 より前のバージョンの PostgreSQL を使用している場合、文字列リテラルの構文はデフォルトで ANSI に準拠しておらず (再構成すれば可能です)、バックスラッシュ文字には特別な意味があります。\'これにより、680 の回答のような攻撃が可能になります。

さらに、バイト文字列をデータ アクセス関数に渡し、データベースがたまたま東アジア文字エンコーディングを使用している場合、マルチバイトの一部である可能性がある でstr_replaceバイト置換を行うという問題が発生します。最初の引用符はマルチバイト シーケンスの一部として食べられ、次に 2 番目の引用符が文字列を閉じます'''(これは、末尾の下位バイトを回避するように設計されている UTF-8 では発生しません。)

使用している DB の適切なエスケープ呼び出し (例: mysql_real_escape_string) を使用するか、パラメーター化されたクエリを使用すると、これらのあいまいで厄介なエッジ ケースについて知る必要がなくなります。

于 2012-07-23T09:16:51.963 に答える
-1

文字列置換用のこの配列はどうですか

$search = array(" ' ", ' " ', " ` ", ' & ', ' , ', ' ; ', ' SELECT ', ' WHERE ', ' AND '); 
于 2014-07-29T10:13:52.843 に答える