3

テーブルの特定の行を削除できる関数を作成しようとしています。この関数をいくつかの異なるテーブルに使用したいので、関数を呼び出すときに、関数のパラメーターの1つをテーブル名にします。これが私がやろうとしていることの例です:

function delete($conn, $table, $id) {
    $stmt = $conn->prepare("DELETE FROM ".$table." WHERE id = :id");
    $stmt->bindParam(":id", $id, PDO::PARAM_INT);
    $stmt->execute();  

    if ($stmt->rowCount() > 0) {
            return true;
    } else {
            return false;
    }
}

私が抱えている問題の1つは、$ table変数がSQLクエリに直接入るため、データベースがSQLインジェクションのリスクにさらされないということです。

他の質問の1つから学んだように、:tableを配置してbindParam関数に追加することはできないため、この関数を安全にする方法がわかりません。何か案は??

4

3 に答える 3

3

テーブルデータをサニタイズする

関数で使用するホワイトリストに登録されたテーブル名の配列を定義できます。

$whitelist = array('table1', 'table2', ...)

次に使用します:

$myTable= array_intersect_keys($table, array_flip($whitelist));

$myTableこれで安全になります。

于 2012-11-21T18:12:50.923 に答える
0

MySQLは現在動的SQL文字列構築をサポートしていませんが、テーブルのホワイトリスト、またはPDOのプリペアドステートメント(冗長、私は知っています)を使用してMySQLプリペアドステートメントを試すことができます。

$sql = "
PREPARE stmt FROM 
'DELETE FROM @tbl WHERE id = :id';
EXECUTE stmt USING :table;
";
$stmt = $db->prepare($sql);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->bindParam(':table', $table);

これはテストされていませんが、役立つ場合があります。

于 2012-11-21T18:15:41.123 に答える
0

メタデータとしてのテーブル名は、行データよりもはるかに制限されているため、テーブル名のサニタイズは、データのサニタイズよりもはるかに信頼性が高いはずです。これはもちろん、PDOの外で消毒することを意味します。

私たちがよく使用するのはPHPインクルードで、配列定義としてすべての有効なテーブル名が含まれているため、検索するだけです。見つからず、インクルードのファイル経過時間が1時間以上の場合は、「 SHOW TABLES」とインクルードを再作成するので、かなり自動魔法です。

于 2012-11-21T18:14:15.740 に答える