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

PHP MySQL SQL 注入攻擊與防範實戰:magic_quotes、型別檢查、預處理

     編輯:MySQL 綜合教學

注入根因雙支柱

  1. `magic_quotes_gpc = Off` 且無手動轉義
  2. 核心:開發者未對輸入進行型別檢查與轉義

第二點才是致命傷:即使 `magic_quotes_gpc = On`,若型別錯誤(如數值欄位未驗證)同樣可注入。

實戰攻擊演示(magic_quotes_gpc = Off)

<?php
if (isset($_POST['f_login'])) {
    $link = mysqli_connect('localhost', 'root', '', 'test');
    $uname = $_POST['f_uname'];
    $pwd   = $_POST['f_pwd'];
    // 直接拼接,極度危險
    $sql = "SELECT * FROM tbl_users WHERE username='$uname' AND password='$pwd' LIMIT 0,1";
    $res = mysqli_query($link, $sql);
    // ...
}
?>
<form method="post">
User: <input name="f_uname"><br>
Pass: <input name="f_pwd" type="password"><br>
<input type="submit" name="f_login" value="登入">
</form>

攻擊 Payload

用戶名:admin' --
密碼:任意
→ SQL 變為:SELECT * FROM tbl_users WHERE username='admin' --' AND password='xxx'
-- 之後被註解,繞過密碼驗證

防範三層防線

1. 輸入驗證與型別強制(第一道防線)

$id = (int)$_GET['id'];           // 強制整數
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT);
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);

2. 參數化查詢 / 預處理語句(核心防線)

$stmt = $mysqli->prepare('SELECT * FROM users WHERE username=? AND password=?');
$stmt->bind_param('ss', $uname, $pwd);
$stmt->execute();

參數與 SQL 結構分離,徹底杜絕注入。

3. 最小權限資料庫帳號(縱深防禦)

  • Web 應用布號僅擁有必要表的 `SELECT/INSERT/UPDATE/DELETE`
  • 禁止 `DROP`、`ALTER`、`GRANT`、`FILE` 等高危權限
  • 不同模組使用不同帳號

magic_quotes_gpc = On 時的殘留風險

// 數值型欄位未驗證
$id = $_GET['id'];  // 攻擊者傳入:1 OR 1=1
$sql = "SELECT * FROM news WHERE id=$id";  // 無引號,magic_quotes 無效
// 結果:全表洩露

結論:永遠不要依賴 magic_quotes,PHP 5.4 已移除。

現代框架自動防護

  • Laravel Eloquent / Query Builder:自動參數綁定
  • ThinkPHP 模型/查詢構建器:自動預處理
  • PDO 直接使用:`$pdo->prepare()->execute([...])`

安全檢查清單

  1. 所有 SQL 使用預處理,零拼接
  2. 數值/日期/列舉等非字串欄位強制型別轉換
  3. 錯誤訊息不回顯給前端(關閉 `display_errors`)
  4. WAF/資料庫審計日誌啟用
  5. 定期掃描弱密碼、舊帳號、過度權限
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved