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

PHP 數據過濾與安全防護:從基礎函數到白名單架構

     編輯:PHP 相關知識

核心原則:永遠不信任外部輸入

所有來自 $_GET、$_POST、$_COOKIE、$_REQUEST、$_SERVER、$_FILES 的數據均視為「污染數據」,必須經過驗證/過濾後才能進入業務邏輯、數據庫或輸出頁面。

基礎過濾函數速查

場景推薦函數/方法說明
SQL 防注入預處理語句PDO::prepare / mysqli_prepare,參數綁定徹底解決注入
HTML 輸出防 XSShtmlspecialchars($str, ENT_QUOTES, 'UTF-8')轉義 < > & ' ",編碼必須指定
Shell 命令參數escapeshellarg() / escapeshellcmd()防命令注入
整數驗證filter_var($v, FILTER_VALIDATE_INT)嚴格類型檢查
浮點數驗證filter_var($v, FILTER_VALIDATE_FLOAT)
郵箱格式filter_var($v, FILTER_VALIDATE_EMAIL)RFC 5322 兼容
URL 格式filter_var($v, FILTER_VALIDATE_URL)
IP 地址filter_var($v, FILTER_VALIDATE_IP)支援 IPv4/IPv6、私有/保留標誌
移除標籤strip_tags($str, '<p><br>')保留允許標籤,屬性仍可能含事件處理器
路徑遍歷防護basename() / realpath() + 白名單禁止 ../ 等目錄跳轉

白名單驗證模式(最佳實踐)

<?php
// 定義允許的字段與規則
$rules = [
    'username' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^[a-zA-Z0-9_]{3,16}$/']],
    'age'      => ['filter' => FILTER_VALIDATE_INT, 'options' => ['min_range' => 1, 'max_range' => 120]],
    'email'    => ['filter' => FILTER_VALIDATE_EMAIL],
    'role'     => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^(admin|editor|viewer)$/']],
];

// 統一過濾輸入
$clean = filter_input_array(INPUT_POST, $rules);

// 檢查是否有驗證失敗
$errors = [];
foreach ($clean as $key => $value) {
    if ($value === false || $value === null) {
        $errors[] = "字段 {$key} 驗證失效或缺失";
    }
}

if ($errors) {
    // 返回錯誤,拒絕處理
    exit(json_encode(['code' => 400, 'msg' => implode('; ', $errors)]));
}

// 此處 $clean 僅包含通過驗證的純淨數據
processBusiness($clean);

歷史遺留項目快速加固(不推薦新項目使用)

<?php
// 全局入口文件頂部引入
if (@get_magic_quotes_gpc()) {
    $_GET    = stripSlashesDeep($_GET);
    $_POST   = stripSlashesDeep($_POST);
    $_COOKIE = stripSlashesDeep($_COOKIE);
    $_FILES  = stripSlashesDeep($_FILES);
}

// 統一轉義(僅用於極舊代碼無法改造時)
function addSlashesDeep(&$val) {
    if (is_array($val)) {
        foreach ($val as &$v) addSlashesDeep($v);
    } elseif (is_string($val)) {
        $val = addslashes($val);
    }
    return $val;
}

// 危險函數檢查(僅作最後防線)
function injectCheck(string $str): bool {
    $patterns = [
        '/union\s+select/i', '/select.*from/i', '/insert\s+into/i',
        '/update.*set/i', '/delete\s+from/i', '/drop\s+table/i',
        '/load_file/i', '/into\s+outfile/i', '/\.\.\//', '/\.\.\\\\/'
    ];
    foreach ($patterns as $p) {
        if (preg_match($p, $str)) return true;
    }
    return false;
}

警告:magic_quotes_gpc 已在 PHP 5.4 移除,addslashes 無法防禦所有注入(如編碼繞過),務必遷移至預處理語句。

輸出編碼上下文區分

  • HTML 內容:htmlspecialchars($str, ENT_QUOTES, 'UTF-8')
  • HTML 屬性:同上,確保屬性用雙引號包裹
  • JavaScript 字符串:json_encode($str)(自動處理引號、換行、Unicode)
  • CSS 值:cssesc()(需引入 polyfill)
  • URL 參數:urlencode($str) / rawurlencode()
  • Shell 參數:escapeshellarg($str)
  • SQL 字面量:禁止手動拼接,唯一正解是預處理參數綁定

現代框架內置防護

Laravel、Symfony、ThinkPHP 等框架提供:

  • CSRF Token 自動驗證
  • Eloquent/ORM 參數綁定防注入
  • Blade/Twig 模板引擎自動 HTML 轉義
  • 驗證器類實現白名單規則
  • 內容安全策略(CSP)中間件

新項目強制使用框架內置機制,避免手工拼裝安全代碼。

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