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

PHP 轉義與資料淨化實戰:防禦 XSS、SQL 注入與資料完整性

     編輯:PHP 相關知識

資料進出邊界的安全防線:輸入過濾、輸出編碼與情境化處理

「不信任任何輸入」是安全開發鐵律。本文整理 PHP 歷史轉義函數演進、情境化處理策略、現代最佳實踐,建立完整資料淨化防護體系。

歷史轉義函數演進與淘汰

函數/特性狀態問題現代替代
magic_quotes_gpcPHP 5.4 移除自動跳脫汙染原始資料、雙重跳脫、誤導安全感手動情境化處理
addslashes()不推薦非資料庫專用、多位元組字元繞過風險PDO Prepared Statements
mysql_real_escape_string()PHP 7.0 移除 (mysql_*)需連線資源、僅限 MySQLPDO::quote() 或參數化查詢
ereg/eregi_replace()PHP 7.0 移除POSIX 正則效能差、不支援 Unicodepreg_replace() / 專用函數

情境化處理策略:正確的工具用在正確的地方

1. 輸出到 HTML 體內容 → htmlspecialchars()

<?php
function h($str, $flags = ENT_QUOTES | ENT_SUBSTITUTE, $encoding = 'UTF-8') {
    return htmlspecialchars($str, $flags, $encoding);
}

// 使用
echo "<div>" . h($userInput) . "</div>";
echo "<input value='" . h($userInput) . "'>";  // ENT_QUOTES 處理單引號
?>
  • ENT_QUOTES:雙引號+單引號皆編碼
  • ENT_SUBSTITUTE:無效編碼字元替換為 而非空字串
  • ENT_HTML5:HTML5 模式(PHP 5.4+)

2. 輸出到 HTML 屬性(已用雙引號包裹)

同 htmlspecialchars($str, ENT_QUOTES),確保單引號也被編碼防止屬性突破。

3. 輸出到 JavaScript 字串字面值

<?php
function jsEscape($str) {
    return json_encode($str, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
}

// 使用
echo "<script>var user = " . jsEscape($name) . ";</script>";

json_encode 自動處理 Unicode、換行、引號、控制字元,最安全。

4. 輸出到 URL 參數

<?php
$url = 'https://example.com/search?q=' . urlencode($keyword);
// 空格→+,特殊字元→%XX

// RFC 3986 標準編碼(空格→%20)
$url = 'https://example.com/search?q=' . rawurlencode($keyword);

5. 輸出到 SQL 查詢 → 參數化查詢(唯一正解)

<?php
// PDO Prepared Statement
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND status = ?');
$stmt->execute([$email, $status]);
$rows = $stmt->fetchAll();

// 命名參數(可讀性更好)
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute([':email' => $email]);

絕對禁止:"SELECT * FROM users WHERE email = '$email'" 字串拼接。

6. 輸出到 Shell 命令

<?php
$cmd = 'convert ' . escapeshellarg($inputFile) . ' ' . escapeshellarg($outputFile);
exec($cmd, $output, $returnCode);

7. 輸出到正則模式

<?php
$pattern = '/^' . preg_quote($userPrefix, '/') . '.*$/';

輸入端驗證與淨化

資料庫欄位型別對應處理(舊代碼遷移參考)

<?php
// 標題/名稱類:去首尾空白、資料庫跳脫
function trans_string_trim($str) {
    $str = trim($str);
    // 現代:參數化查詢不需跳脫
    // 兼容舊代碼:$str = $pdo->quote($str); // 含引號
    return $str;
}

// 文章/textarea:保留換行、資料庫跳脫
function trans_string($str) {
    // 現代:參數化查詢
    return $str;
}

// 顯示在網頁:HTML 編碼 + 換行轉 br
function trans_web($string) {
    $string = htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
    $string = nl2br($string);  // 換行 → 
return $string; } // 顯示在 span/屬性:編碼 + 空白保留 function trans_span($string) { $string = htmlspecialchars($string, ENT_QUOTES, 'UTF-8'); $string = str_replace(' ', ' ', $string); return $string; } ?>

關鍵原則總結

  1. 輸入驗證 ≠ 輸出編碼:兩者互補,缺一不可
  2. 情境決定編碼方式:HTML/JS/URL/SQL/Shell 各有專用函數
  3. 參數化查詢優於跳脫:SQL 注入防禦首選 Prepared Statements
  4. 編碼在輸出時進行:儲存原始資料,輸出時依情境編碼
  5. 統一封裝 Helper 函數:h(), js(), url() 降低誤用機率

建立專案級的「資料流向安全規範文件」,明確每個輸入來源、儲存格式、輸出情境對應的處理函數,是團隊協作安全的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
資料類型驗證方法淨化方法
整數filter_var($v, FILTER_VALIDATE_INT)(int)$v
浮點數filter_var($v, FILTER_VALIDATE_FLOAT)(float)$v
Emailfilter_var($v, FILTER_VALIDATE_EMAIL)無(驗證通過即可用)
URLfilter_var($v, FILTER_VALIDATE_URL)無
IPfilter_var($v, FILTER_VALIDATE_IP)無
布林filter_var($v, FILTER_VALIDATE_BOOLEAN)filter_var($v, FILTER_VALIDATE_BOOLEAN)
字串長度mb_strlen($v) <= $maxmb_substr($v, 0, $max)
白名單值in_array($v, $allowed, true)無