首頁 > 資料庫 > mysql教程 > 如何在準備語句中安全地使用參數化表名來防止 SQL 注入?

如何在準備語句中安全地使用參數化表名來防止 SQL 注入?

Mary-Kate Olsen
發布: 2025-01-23 18:08:10
原創
368 人瀏覽過

How Can We Securely Use Parameterized Table Names in Prepared Statements to Prevent SQL Injection?

準備好的語句中的參數化表名:一個困境

儘管mysqli_stmt_bind_param 已被證明可以有效防止SQL 注入,但當當變數影響時,它會遇到限制涉及到表名。如提供的程式碼片段所示:

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();
}
登入後複製

$new_table 的有問題的串聯引入了 SQL 注入漏洞。試著用另一個佔位符取代它,如以下程式碼片段所示,失敗:

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();
}
登入後複製

準備語句的限制

核心問題在於無法準備好的語句來保護定義SQL 語句結構的參數,例如表名。這是因為準備好的語句只允許參數值不改變語句的意思。由於表名決定了 SQL 語句的有效性,因此在執行期間修改它們可能會使其無效。

即使使用像 PDO 這樣的資料庫接口,透過在將參數發送到資料庫之前替換參數來模擬準備好的語句,佔位符值仍然是SQL 語句中包含的字串。結果,SELECT FROM ?使用 mytable 作為參數最終會將 SELECT FROM 'mytable' 傳送到資料庫,使其無效。

降低風險

最安全的方法仍然是在字串中使用 $mytable,但它必須附帶一個用於檢查用戶輸入的表白名單。這可以防止惡意行為者在任意表上執行 SQL 語句。因此,以下程式碼示範了安全實作:

if (whitelisted_tables($mytable)) {
    $statement = $mysqli->prepare("INSERT INTO $mytable VALUES (?,?,?,?,?,?,?);");
    mysqli_stmt_bind_param( $statment, 'sssisss', $Partner, $Merchant, $ips, $score, $category, $overall, $protocol );
    $statement->execute();
}
登入後複製

以上是如何在準備語句中安全地使用參數化表名來防止 SQL 注入?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板