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

PHP 表單輸入過濾:HTML/JS 危險代碼清洗與 XSS 防禦實戰

     編輯:PHP 綜合知識

用戶提交的表單資料若直接輸出至 HTML 頁面,極易導致 XSS(跨站腳本攻擊)、版面錯亂、惡意重導向。本文提供兩種實用的 PHP 過濾函數:基礎版(htmlspecialchars + addslashes)與進階版(正則深度清洗),並解析適用場景與局限。

方案一:基礎過濾函數 PostGet()

針對單一參數,自動判斷 GET/POST,處理魔術引號相容,輸出經 htmlspecialchars 轉義的安全字串。

function PostGet($key, $isPost = false) {
    if (empty($key)) die('Parameter name required');

    $source = $isPost ? $_POST : $_GET;
    $raw = $source[$key] ?? '';

    // PHP 5.4+ 已移除 magic_quotes_gpc,此判斷僅相容舊環境
    if (get_magic_quotes_gpc()) {
        $raw = stripslashes($raw); // 先還原
    }

    // 核心:HTML 實體化,防 XSS
    $safe = htmlspecialchars($raw, ENT_QUOTES | ENT_HTML5, 'UTF-8');

    // 可選:資料庫層再加 addslashes(不推薦,應用參數化查詢)
    // return addslashes($safe);

    return $safe;
}

// 使用
$name = PostGet('username');        // GET
$content = PostGet('content', true); // POST

方案二:進階深度清洗 uhtml()

針對富文本、評論等允許部分 HTML 的場景,移除高危標籤(script, iframe, style...)、行內事件(onload, onclick...)、多餘空白。

function uhtml($str) {
    if (!is_string($str)) return '';

    $patterns = [
        '/\s+/'                          => ' ',                    // 合併空白
        '/<(\/?)(script|iframe|style|html|body|title|link|meta|\?|\%)([^>]*?)>/isU' => '<\1\2\3>', // 全形化危險標籤(或替換為空字串直接刪除)
        '/(<[^>]*)on[a-z]+\s*=([^>]*>)/isU' => '\1\2',              // 移除行內事件 onxxx=
    ];

    $str = preg_replace(array_keys($patterns), array_values($patterns), $str);
    return $str;
}

// 使用
$comment = uhtml($_POST['comment']);
echo $comment; // 安全輸出

正則模式解析

模式作用說明
/\s+/合併連續空白防 CSS 注入、版面撐破
/<(\/?)(script|iframe|style|html|body|title|link|meta|\?|\%)([^>]*?)>/isU匹配高危標籤isU 單行模式+非貪婪;替換為全形括號保留可見性,或 '' 直接刪除
/(<[^>]*)on[a-z]+\s*=([^>]*>)/isU移除行內事件屬性onload, onclick, onerror 等 XSS 主要載體

現代 XSS 防禦鐵律(超越過濾函數)

  1. 輸出編碼優於輸入過濾:在**輸出時**根據語境編碼(HTML 用 htmlspecialchars、JS 用 json_encode、URL 用 urlencode、CSS 用 cssesc),而非入庫前清洗。
  2. 使用模板引擎自動逃逸:Blade ({{ $var }}), Twig ({{ var|e }}), ThinkPHP ({$var}), Latte 等預設自動 HTML 轉義。
  3. CSP (Content-Security-Policy) 標頭:Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-xxx'; 徹底禁用內聯腳本、外部非白名單腳本。
  4. HttpOnly Cookie:setcookie(..., true) 防止 JS 竊取 Session ID。
  5. 富文本白名單庫:若需允許部分 HTML,使用 HTMLPurifier(PHP 最完整標準庫)而非自寫正則。

方案選擇指南

場景推薦處理
一般表單欄位(姓名、標題、搜尋關鍵字)輸出時 htmlspecialchars($val, ENT_QUOTES, 'UTF-8')
純文字內容(備註、簡介)同上,或儲存前 strip_tags + 輸出轉義
富文本編輯器內容HTMLPurifier 清洗 → 儲存 → 輸出時信任(或加 CSP)
API JSON 回應json_encode 自動處理,勿手工拼接 JSON
舊專案快速修補方案一 PostGet() 統一入口,再逐步遷移至模板自動逃逸

總結

PostGet() 適合快速統一入口過濾,uhtml() 適用於需保留部份 HTML 的舊系統。**現代專案請棄用手工過濾,全面採用模板引擎自動逃逸 + CSP + HTMLPurifier** 三層防線,從根源杜絕 XSS。

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