首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP SQL 注入攻擊原理深度解析與防禦最佳實踐

     編輯:PHP 綜合知識

兩大核心成因

  1. magic_quotes_gpc = Off(舊版 PHP 預設關閉,新版已移除)
  2. 開發者未對輸入進行型別檢查與轉義 —— 這是根本原因。

即使開啟 `magic_quotes_gpc`,若未驗證數值型欄位,仍可被注入。

攻擊場景一:字串型欄位注入(magic_quotes_gpc = Off)

$sql = "SELECT * FROM users WHERE username='$_POST[user]' AND pwd='$_POST[pwd]'";

輸入:`user = admin' OR 1=1 #` → SQL 變為:

SELECT * FROM users WHERE username='admin' OR 1=1 #' AND pwd='...'

註解符 `#` 截斷後續查詢,繞過驗證。若知表結構可用 `UNION SELECT` 竊取資料。

攻擊場景二:數值型欄位注入(magic_quotes_gpc = On 也失效)

$sql = "SELECT * FROM users WHERE uid=$_POST[uid] AND pwd='$_POST[pwd]'";

輸入:`uid = 1001 OR 1=1 #` → SQL:

SELECT * FROM users WHERE uid=1001 OR 1=1 # AND pwd='...'

數值型欄位**不需引號**,`magic_quotes` 不會轉義,直接注入成功。MySQL 5.x+ 已嚴格型別,但舊版或未嚴格模式下極危險。

防禦鐵律:參數化查詢(Prepared Statements)

<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmt = $pdo->prepare('SELECT * FROM users WHERE username = ? AND pwd = ?');
$stmt->execute([$_POST['user'], $_POST['pwd']]);
$user = $stmt->fetch();

**優點**:資料與指令分離,徹底杜絕注入;效能佳(重複執行只編譯一次)。

輔助防禦層

措施說明
型別強制轉換`$id = (int)$_GET['id'];` 確保數值型
白名單驗證`in_array($sort, ['asc','desc'])` 限制可選值
最小權限資料庫帳號僅授予必要 CRUD 權限,禁止 DROP/ALTER
關閉錯誤顯示`display_errors=Off`,記錄至 log,避免洩露結構
WAF / 參數過濾應用層過濾可疑關鍵字(非首選,易誤殺/繞過)

錯誤示範:手動拼接 + addslashes

$sql = "SELECT * FROM t WHERE c = '" . addslashes($_GET['c']) . "'";
// 危險:多位元組編碼繞過、邊界情況、維護成本高

安全參數獲取函式範例(教學用,生產請用 PDO)

function getParam(string $name, $default = '', string $type = 'string')
{
    $val = $_GET[$name] ?? $_POST[$name] ?? $default;
    $val = trim($val);

    if ($type === 'int') {
        return is_numeric($val) ? (int)$val : (int)$default;
    }

    // 字串:HTML 編碼輸出端處理,資料庫端用參數化查詢
    return $val;
}

總結

  1. **永遠使用參數化查詢(PDO / mysqli_prepare)**。
  2. 輸入端做**型別驗證**,輸出端做**編碼**(HTML/JS/SQL/Shell)。
  3. 資料庫帳號**最小權限**,錯誤資訊**不顯示給前端**。
  4. 定期進行滲透測試與代碼審計。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved