首頁 >資料庫 >mysql教程 >準備好的語句可以處理參數化表名以防止 SQL 注入嗎?

準備好的語句可以處理參數化表名以防止 SQL 注入嗎?

DDD
DDD原創
2025-01-23 17:56:09846瀏覽

Can Prepared Statements Handle Parameterized Table Names to Prevent SQL Injection?

準備好的語句:它們可以處理參數化表名稱嗎?

本文解決了預處理語句是否可以有效處理參數化表名以防止 SQL 注入漏洞的關鍵問題。

問題:

直接將使用者提供的資料(包括表名)嵌入 SQL 查詢中是一個主要的安全風險。 考慮這個例子:

<code class="language-php">function insertRow( $db, $mysqli, $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol )
{
    $statement = $mysqli->prepare("INSERT INTO " .$new_table . " VALUES (?,?,?,?,?,?,?);");
    mysqli_stmt_bind_param( $statment, 'sssisss', $Partner, $Merchant, $ips, $score, $category, $overall, $protocol );
    $statement->execute();
}</code>

如果 .$new_table. 未正確清理,串聯 $new_table 會使該函數容易受到 SQL 注入的攻擊。

嘗試參數化:

緩解此問題的常見嘗試是嘗試參數化表名稱:

<code class="language-php">function insertRow( $db, $mysqli, $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol )
{
    $statement = $mysqli->prepare("INSERT INTO (?) VALUES (?,?,?,?,?,?,?);");
    mysqli_stmt_bind_param( $statment, 'ssssisss', $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol );
    $statement->execute();
}</code>

現實:

不幸的是,這種方法失敗了。 準備好的語句旨在防止運行時值注入,而不是防止更改SQL查詢本身的結構。 資料庫解析器將表名解釋為查詢結構的一部分,而不是執行時間參數。 用佔位符替換它會導致無效的 SQL。

即使系統提供預先準備語句模擬(例如 PDO),結果也將是無效查詢(例如,SELECT * FROM 'mytable' 而不是 SELECT * FROM mytable)。

解:

處理使用者提供的表名時防止 SQL 注入的唯一可靠方法是採用嚴格的白名單。 這涉及預先定義允許的表名列表,並確保在查詢中使用之前對照此白名單檢查任何用戶提供的表名。 切勿直接使用使用者輸入來建構涉及表名的 SQL 查詢。

以上是準備好的語句可以處理參數化表名以防止 SQL 注入嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn