2

重複の可能性:
mysql_real_escape_string() は SQL インジェクションから完全に保護しますか?

私のページでフォームを作成しました。私がやりたいことは、phpコーディングでフィールド値を投稿するときに、strip_tagsmysql_real_escap_stringas の両方を使用したいことです:

$res = stript_tags(mysql_real_escape_string($_POST['name']));

上記のコーディングは、入力フィールド名を安全に送信するのに正しいですか、それとも送信時に問題が発生しますか?

4

4 に答える 4

2

それ自体は、これで問題なく動作するはずです。しかし、個人的には、まったく使用しないことをお勧めしますmysql_real_escape_stringmysql_*非推奨になっている拡張機能を使用していると考えるのは正しいと思います。自分に有利に働き、またはのいずれPDOmysqli_*に切り替えてください。できれば PDO に切り替えてください。

これらは、準備されたステートメントをサポートする、より最新の拡張機能です。いくつかのリンクについては、
こちらの回答を参照してください。また、準備されたステートメントが手動でデータをエスケープするよりもはるかに安全な理由については、Bobby テーブルを参照してください。

@phant0m が言うように: の使用はmysql_real_escape_string完全な証拠ではありません (彼のコメントのリンクを参照してください)。strip_tags特に andのような関数を使用する場合、いくつかの落とし穴がありstripslashesます。データを処理しているとき、ある時点でデータに , のようなものが含まれていることは想像にFoo\'s Bar難くありません。

magic_quotes_sybase がオンの場合、バックスラッシュは削除されませんが、代わりに 2 つのアポストロフィが 1 つに置き換えられます。

の結果がどうなるかを考えてみてくださいstripslashes(mysql_real_escape_string($data));...

を使用する場合、許容されるタグその属性を保持することstrip_tagsに注意することが重要です。これには、スラッシュ、コロン、セミコロン、ダッシュ、引用符、およびクエリを台無しにしたくないその他のさまざまな文字が含まれる場合があります...その他の考えられる問題についてで、この投稿を見てください
strip_tags

于 2012-11-28T12:20:49.937 に答える
2

まず、mysql_real_escape_string関数はSQL インジェクションを (ある程度) 防ぐのに役立ちますが、データベースを保護するための最良の方法ではありません。異なる接続文字セットが適切に使用されていない場合、関数には既知の脆弱性があり、さらに重要なことに、mysql 関数は推奨されなくなりました。PHP.net を引用するには:

この拡張機能の使用はお勧めできません。

SQL インジェクションを防ぐ最善の方法は、準備済みステートメントを使用することです。準備済みステートメントを使用するには、PDOオブジェクトまたはmysqliに切り替える必要があります。

次に、入力時にstrip_tagsを実際に使用するべきではありません。なんで?ユーザーがタグ内に何かを入力すると、データの整合性が失われるためです。個人的には、strip_tags は出力でのみ使用する必要があると思います。つまり、ユーザーが入力したデータを表示しているときです。

第三に、strip_tags はすべての XSS 攻撃を防ぐわけではありません。個人的には、XSS を防ぐためです。私は次のようなものに行きます:

echo htmlspecialchars($stringToOutput, ENT_QUOTES, 'UTF-8');

htmlspecialcharsは、すべての特殊文字を関連する HTML エンティティに変換します。

于 2012-11-28T12:23:13.110 に答える
1

手動で行うのではなく、何らかのフレームワークを使用することを検討する必要があります。Zend_DbまたはPDO (準備済みステートメントを読む)を見てください。

PDO の例:

$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}
$st = $dbh->prepare( '
    INSERT INTO fruits( name, colour )
    VALUES( :name, ":colour" )
';
$st->execute( array( ':name' => 'Apple', ':colour' => 'red' ) );
于 2012-11-28T12:22:03.313 に答える
1

投稿したコードは機能します。ただし、文字列は可能な限り最後にエスケープすることをお勧めします。実際のクエリの前にエスケープされた文字列を操作したくないため、これにより変数がクリーンに保たれます。

例:

$query = "SELECT * FROM tablename WHERE column1 = '". mysql_real_escape_string($_POST['name']) ."'";

また、mysql_* 関数はもう維持されていないことに注意してください。代わりにmysqli_*を使用できますが、最善の方法は、 PDOで準備済みステートメントを使用することです。

于 2012-11-28T12:20:35.047 に答える