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

PHP 安全防護指南:SQL 注入與 XSS 攻擊原理、實戰範例與修復方案

     編輯:PHP 綜合知識

SQL 注入與跨站腳本攻擊 (XSS) 是 Web 應用最常見的兩大安全漏洞。本文透過實際程式碼示範攻擊原理,並提供針對性修復方案與最佳實踐。

一、SQL 注入攻擊

1.1 脆弱程式碼範例

<?php
// 直接拼接使用者輸入,極度危險
$conn = mysql_connect("localhost", "root", "123456");
mysql_select_db("test1");

$user = $_POST['uid'];
$pwd  = $_POST['pass'];

// 惡意輸入:uid = "admin' --" 即可繞過密碼驗證
$sql = "SELECT * FROM admin WHERE username = '$user' AND password = '$pwd'";
$result = mysql_query($sql);
if (mysql_num_rows($result) > 0) {
    echo "登入成功";
} else {
    echo "帳號或密碼錯誤";
}
?>

1.2 攻擊載荷示例

  • uid: admin' -- → SQL 變為 WHERE username = 'admin' --' AND password = '...',註解掉密碼檢查。
  • uid: ' OR '1'='1 → 條件永真,返回第一筆資料 (通常是管理員)。
  • uid: ' UNION SELECT null, username, password FROM admin -- → 聯合查詢竊取所有帳密。

1.3 修復方案:參數化查詢 (Prepared Statements)

唯一根治之道,將 SQL 邏輯與資料分離:

<?php
// 使用 PDO (推薦)
$pdo = new PDO("mysql:host=localhost;dbname=test1;charset=utf8", "root", "123456");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmt = $pdo->prepare("SELECT * FROM admin WHERE username = ? AND password = ?");
$stmt->execute([$_POST['uid'], $_POST['pass']]); // 參數綁定,自動處理跳脫
$user = $stmt->fetch();
if ($user) {
    echo "登入成功";
} else {
    echo "帳號或密碼錯誤";
}
?>

mysqli 寫法:

$stmt = $mysqli->prepare("SELECT * FROM admin WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $_POST['uid'], $_POST['pass']);
$stmt->execute();

1.4 輔助防護 (非替代方案)

  • mysql_real_escape_string():舊版 mysql_* 專用,易漏掉、編碼問題多,**不推薦**。
  • 輸入驗證/白名單:限制長度、字元集、格式 (如 email、手機號)。
  • 最小權限原則:資料庫帳號僅授予必要權限 (SELECT/INSERT),禁止 DROP、FILE 權限。
  • WAF (Web Application Firewall):作為第二道防線,不可倚賴。

二、XSS 跨站腳本攻擊

2.1 攻擊類型

類型特徵範例
反射型惡意腳本經 URL 參數反射回響應頁面search?q=
儲存型惡意腳本儲存於資料庫,所有瀏覽者受害留言板、評論區植入
DOM 型純前端 JS 處理 URL 片段導致document.write(location.hash)

2.2 脆弱程式碼

<?php
// 直接輸出未過濾的使用者輸入
echo $_POST['comment']; 
?>
<!-- 攻擊者提交: -->

2.3 修復方案:輸出編碼 (Context-Aware Encoding)

根據輸出位置選擇正確編碼函數:

輸出語境PHP 函數範例
HTML 內文/屬性htmlspecialchars($str, ENT_QUOTES, 'UTF-8')<div></div>
JavaScript 字串json_encode($str) (含引號)var msg = ;
URL 參數urlencode($str)<a href="?q=">
CSS 值無內建函數,需嚴格白名單僅允許顏色代碼、數字等

2.4 輔助工具:HTMLPurifier

若需允許使用者輸入有限 HTML (如富文本編輯器),**必須使用白名單過濾器**:

require_once 'HTMLPurifier.auto.php';
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.Allowed', 'p,b,i,u,em,strong,a[href|title],ul,ol,li,br,img[src|alt]');
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify($dirty_html);

三、綜合防護清單

  1. 資料庫層:全域強制參數化查詢,禁止字串拼接 SQL。
  2. 輸入層:驗證長度、型別、格式;拒絕異常字元 (但不依賴過濾)。
  3. 輸出層:模板引擎預設啟用自動逃逸 (Blade、Twig、Smarty 皆內建)。
  4. HTTP 標頭:Content-Security-Policy 限制腳本來源;X-Content-Type-Options: nosniff;HttpOnly Cookie 防竊取。
  5. 框架層:使用 Laravel、Symfony、CodeIgniter 等現代框架,內建 CSRF 保護、查詢建構器、輸出逃逸。
  6. 定期掃描:整合 OWASP ZAP、SonarQube、PHPStan 靜態分析。

結語

安全是系統工程,**參數化查詢解決 SQL 注入,語境感知輸出編碼解決 XSS**。沒有銀彈,唯有分層防禦、持續更新、程式碼審查才能降低風險。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved