首頁 >資料庫 >mysql教程 >如何防止PHP應用中的SQL注入?

如何防止PHP應用中的SQL注入?

Linda Hamilton
Linda Hamilton原創
2025-01-25 22:17:08356瀏覽

How Can I Prevent SQL Injection in PHP Applications?

防止PHP中的SQL注入

SQL注入是一種漏洞,當未經修改的使用者輸入錯誤地插入SQL查詢時就會出現這種漏洞。這可能導致攻擊者執行任意SQL程式碼,進而對應用程式造成災難性後果。

為了防止SQL注入,至關重要的是將資料與SQL分離,確保資料始終保持為數據,而絕不會被SQL解析器解釋為命令。這可以透過使用帶有參數的預處理語句來實現,預處理語句將SQL查詢與任何參數分開傳送到資料庫伺服器進行解析。這樣,攻擊者就無法注入惡意SQL。

有兩種方法可以實現:

  • 使用PDO(適用於任何支援的資料庫驅動程式)
<code class="language-php">$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(['name' => $name]);

foreach ($stmt as $row) {
    // 处理 $row
}</code>
  • 使用MySQLi(適用於MySQL)

PHP 8.2 :

<code class="language-php">$result = $db->execute_query('SELECT * FROM employees WHERE name = ?', [$name]);
while ($row = $result->fetch_assoc()) {
    // 处理 $row
}</code>

PHP 8.1及更低版本:

<code class="language-php">$stmt = $db->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name); // 's' 指定变量类型 -> 'string'
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    // 处理 $row
}</code>

如果您連接到非MySQL資料庫,您可以參考特定於驅動程式的第二個選項(例如,PostgreSQL的pg_prepare()pg_execute())。 PDO是一個通用的選擇。

正確的連接配置

使用PDO存取MySQL資料庫時,預設不會使用真正的預處理語句。為了解決這個問題,需要停用預處理語句的模擬。以下是如何使用PDO建立連線的範例:

<code class="language-php">$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8mb4', 'user', 'password');

$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);</code>

對於MySQLi,需要執行相同的操作:

<code class="language-php">mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // 错误报告
$dbConnection = new mysqli('127.0.0.1', 'username', 'password', 'test');
$dbConnection->set_charset('utf8mb4'); // 编码</code>

說明

您傳遞給prepare的SQL查詢由資料庫伺服器解析和編譯。透過指定參數(無論是?還是命名參數,如上面的:name範例),您告訴資料庫核心您想要根據什麼進行篩選。然後,當呼叫execute時,預處理查詢會與您提供的參數值結合。

重要的是,參數值與已編譯的查詢結合,而不是與SQL字串結合。 SQL注入透過欺騙腳本,在建立要傳送到資料庫的SQL時包含惡意字串來運作。因此,透過將實際的SQL與參數分開發送,您可以降低獲得意外結果的風險。

使用預處理語句傳送的任何參數都將被簡單地視為字串(儘管資料庫核心可能會執行一些最佳化,因此參數也可能是數字)。在上面的範例中,如果變數$name包含'Sarah'; DELETE FROM employees,結果將只是搜尋字串"'Sarah'; DELETE FROM employees ",您的表格不會被清空。

使用預處理語句的另一個優點是,如果您在同一個會話中執行多次相同的查詢,則只解析和編譯一次,從而提高速度。

以上是如何防止PHP應用中的SQL注入?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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