1

私は一般的なSQLインジェクションについて多くのことを読んだので、それらを修正する方法に興味を持ちました。以前は addslashes()、それが適合すると(ひどく)考えていました。それから私はそれmysql(i)_real_escape_string()がよりもはるかに便利で信頼できることを発見しましたaddslashes()。それ以来使っていますmysqli_real_escape_string()が、最近はよくわからないことがあります。mysqlと文字セットにデータを送信する際に問題が発生しました。それで、もう一度検索しましたが、多くのユーザーは、それSET NAMES UTF8がすべてを正しく行う方法であると言います。しかし、そのクエリを使用すると機能しmysqli_real_escape_string()なくなることを読みました。

結局、私は少し混乱しました。

SQLステートメントをエスケープする正しい方法は何ですか?

を使用して考えられるエクスプロイトは何SET NAMES UTF8ですか?

mysqli_set_charset()指定された文字セットで接続を通信させる正しい方法はありますか?

mysqli_sey_charset()mysqlの内部変数はプロセスで変更されていますか?

ありがとう

4

4 に答える 4

2

mysqliプリペアドステートメントを使用して、SQLインジェクションを回避できます。文字セットのエンコーディングについて心配する必要はありません。

リンクからの例:

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$city = "Amersfoort";

/* create a prepared statement */
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {

    /* bind parameters for markers */
    $stmt->bind_param("s", $city);

    /* execute query */
    $stmt->execute();

    /* bind result variables */
    $stmt->bind_result($district);

    /* fetch value */
    $stmt->fetch();

    printf("%s is in district %s\n", $city, $district);

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>
于 2012-08-08T11:42:38.607 に答える
0

手動で作成されたクエリの受け渡しは、下位互換性の懸念があるためにのみサポートされています。最新のアプリケーションは決してそれを行うべきではなく、代わりにプリペアドステートメントを使用してください。

そうは言っても、手動で構築されたクエリを使用することに完全に取り掛かっている場合、それらをエスケープする適切な方法は、mysql_real_escape_string()を使用し、エンコーディングをUTF-8に設定することです。

詳細については、OWASPサイトをご覧ください:https ://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

于 2013-03-08T22:11:27.157 に答える
0

接続オブジェクトの文字セットを明示的に設定する限り、問題はありません。

mysql_set_charset('utf8', $db); // for mysql
$db->set_charset('utf8'); // for mysqli

文字セットに関する同じ問題がPDOプリペアドステートメントにも当てはまるため、PDOが推奨される方法ですが、この場合は安全ではありません。

mysqli_real_escape_string()定義された文字セットで使用しても問題はありません。接続オブジェクトとHTMLページにUTF-8を使用するように注意してください。これにより、多くの問題を回避できます。

このトピックについて私が見つけた最も良い説明は、PHPの作者であるircmacellから、1回はmysql_real_escape_string()用、もう1回はPDO用に書かれています。

于 2013-03-08T23:35:31.267 に答える
0

質問と回答の両方で多くの誤った情報を訂正するためだけに。

  1. 「ステートメント」ではなく、文字列リテラル。「SQLステートメント」をエスケープすることは、インジェクションへの簡単な方法です。文字列のみをエスケープする必要がありますが、他のクエリパーツでは、明確で完全に異なるフォーマットが必要であり、エスケープしても少しは効果がありません。
  2. エスケープ/エンコーディングの混乱はすべて、GBKなどの一部のマージナルエンコーディングにのみ接続されています。UTF-8を使用すると、addslashes()も使用できます。
  3. 5.3 PDOは、DSNで設定されている限り、クライアントエンコーディングの設定で問題ありません。

SQLステートメントをエスケープする正しい方法は何ですか?

PHPでは、データベースに文字列を送信するときに、htmlspecialchars()を使用して不正な文字を処理する必要がありますか、それとも正規表現を使用する必要がありますか?

SET NAMES UTF8を使用して考えられるエクスプロイトは何ですか?

なし

mysqli_set_charset()は、指定された文字セットで接続を通信させる正しい方法ですか?

もちろん。
HTMLページで使用される実際の文字セットを使用する必要があります。

于 2013-03-09T05:37:48.160 に答える