1

プリペアドステートメントの使用とSQLインジェクションへの影響に気付く前に、このコードを作成しました。これで、プリペアドステートメントを使用して配列をフェッチするのがいかに面倒かについても認識しています。したがって、このコードは、ユーザーが送信した情報を使用して行をフェッチしないため、安全に使用できるかどうか疑問に思いました。

これは、セッションIDを使用してdbテーブルの行を識別することであり、セッションはlogin_check関数などによって保証されます。

$username = $_SESSION['username'];
$select = mysqli_query($link, " SELECT product_id, product_title, product_value                             
                                FROM product
                                WHERE user_id='$username'");

while ($row = mysqli_fetch_assoc($select))
{
    $product[] = array(
            'product_id' => $row['product_id'], 
            'product_title' => $row['product_title'], 
            'product_value' => $row['product_value']);
}

準備されたステートメントを知るまでは順調に進んでいたので、この問題に関するいくつかの情報をいただければ幸いです。

編集
だから、私はちょっと別の方向に行き、このクエリのために配列部分を完全にスキップしました。代わりに、私は準備されたステートメントを使用して、次のようなことをしました。

$select_stmt = $db->prepare("SELECT etc...)
$select_stmt->bind_param("CODE")
$select_stmt->execute();
等々..

しかし、問題は、私のbind_resultが14個の変数でかなり大きくなった(?)ということです。おそらくこれはばかげた質問ですが、単一の配列を使用する従来の方法と比較して、私のサイトの速度が低下しますか(14が「大きい」と見なされる場合)?これは一般的なクエリであり、多くのユーザーが同時に頻繁に使用することを願っています。プリペアドステートメントは私にとって新しいものです。

助けてくれたsofarに感謝します。

4

2 に答える 2

1

ユーザー名がたとえばJean D'arc、mysqlサーバーに到達する文字列である場合は次のようになります

SELECT
  product_id, product_title, product_value
FROM
  product
WHERE
  user_id='Jean D'arc'

その結果、解析エラーが発生します。SQLステートメント内
のパラメーターを適切にエンコード/エスケープすることは、ユーザーからの悪意のある入力を防ぐためだけでなく、ステートメントを壊す可能性のある文字が含まれていないことを(絶対確実に)確認できないすべてのパラメーターに対して必要です。(小さな)疑問がある場合は、パラメーターをエンコード/エスケープするか、単にプリペアドステートメントを使用してください。

于 2012-08-24T12:25:37.677 に答える
1

プリペアドステートメントを調べる必要があります。これは、mysqliの多くの利点の1つです。SQLインジェクションを気にすることなく変数を挿入できます。mysqli_real_escape_stringほとんどの場合は機能しますが、攻撃を回避するための真に安全な方法は、プリペアドステートメントだけです。

マニュアルからの例:

<?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();
}
于 2012-08-24T13:37:56.923 に答える