2
function Query()
{
    $args = func_get_args ();

    if (sizeof ($args) > 0)
    {
         $query = $args[0];

         for ($i = 1; $i < sizeof ($args); $i++)
                $query = preg_replace ("/\?/", "'" . mysql_real_escape_string ($args[$i]) . "'", $query, 1);
    }
    else
    {
          return FALSE;
    }

私はこのような機能を持っています。基本的に、次のようなクエリを作成します。

$this->Query('SELECT * FROM USERS WHERE Username = ? AND Points < ?', $username, $points);

現在、非推奨の機能をサポートしていますが、私のクラスで置き換えるのと同じくらい簡単にmysql適応できます。mysqlimysqlmysqli

これは、SQL インジェクション攻撃に対して信頼できる安全なアプローチですか? すべてのクエスチョン マークは によって自動的にサニタイズされてmysql_real_escape_stringおり、これまで問題はありませんでしたがmysqli_real_escape_string、サニタイズに使用する必要がありますか?

mysqli の準備済みステートメントについては知っていますがbindParam、変数ごとに使用するのは少しやり過ぎのようです。

どう思いますか?

4

3 に答える 3

2

バインドされたパラメーターを使用することはやり過ぎではなく、必須です。より効率的にエスケープしてパラメーターを準備します。

$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);

$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;

/* execute prepared statement */
mysqli_stmt_execute($stmt);

それは本当にやり過ぎのように思えますか?

ドキュメンテーション

于 2013-03-13T15:55:54.720 に答える
1

今日は本当に素晴らしい日でした - 賢明なデータベース抽象化レイヤーを続けて作成する 2 回目の良い試みです。

サニタイズに mysqli_real_escape_string を使用する必要がありますか?

いいえ。この関数は何もサニタイズしない
からです。

ただし、SQL 文字列リテラルをフォーマットするには、この関数は必須であり、回避または置換することはできません。
したがって、この関数を正確に正しい方法で使用して、文字列のみをフォーマットし、無条件にフォーマットしています。したがって、 ? を使用できる限り、
クエリは完全に安全です。マークを付けて実際のデータを置き換えます(そして、関数を使用してSQLエンコーディングを設定している限り、ニッチピックでも不平を言うようにしmysql(i)_set_charset()ます)。

誰かがあなたのアプローチが壊れていると言う場合は、特定の脆弱性を示すための証明コードの完全なスニペットを要求してください。

ただし、いくつかの重要なことに注意を向けさせてください。

  1. 動的 SQL クエリ パーツは、文字列のみに限定されません。たとえば、次の 2 つのクエリは関数では機能しません。

    SELECT * FROM table LIMIT ?,?
    SELECT * FROM table ORDER BY ?
    

    数字と識別子には異なるフォーマットが必要だからです。そのため、タイプヒント付きの
    プレースホルダー を使用して、関数に適用する形式を伝えることをお勧めします

  2. クエリを実行することは、仕事の一部にすぎません。結果も出す必要があります。不要な呼び出しでコードを肥大化させずに、それらを取得してみませんか?
  3. リテラルを挿入する方法があるはずです ? それらを解析せずにクエリにマークします。

私のクラスを見てください。これは、あなたのものとまったく同じ原則に基づいて構築されていますが、上で述べた改善が加えられています。1つか2つのアイデアを借りることが有用であるか、少なくとも価値があると思うことを願っています.

于 2013-03-13T19:33:40.587 に答える
0

mysql の代わりに mysqli を使用する場合。mysqli_real_escape_string を使用する方がよいでしょう。パラメータの順序が変更されていることに注意してください。(% と _ はまだエスケープされていません)

于 2013-03-13T16:03:47.030 に答える