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

Laravel 5/6/7/8/9/10 防 XSS 跨站腳本攻擊:HTMLPurifier 整合與最佳實踐

     編輯:PHP 綜合知識

為什麼 Laravel 內建不夠?

  • {!! $var !!} 直接輸出未轉義 HTML,極高風險。
  • {{ $var }} 雖自動 htmlspecialchars,但無法處理「允許部分 HTML 標籤(如 <b>、<a>)」的富文本需求。
  • 需白名單過濾:只保留安全標籤/屬性,移除 <script>、onerror、style="expression(...)" 等攻擊向量。

方案:mews/purifier(HTMLPurifier Laravel 封裝)

1. 安裝

composer require mews/purifier

2. 註冊服務提供者與 Facade(Laravel 5.5+ 自動發現,通常無需手動)

// config/app.php (若未自動發現)
'providers' => [
    Mews\Purifier\PurifierServiceProvider::class,
],
'aliases' => [
    'Purifier' => Mews\Purifier\Facades\Purifier::class,
]

3. 發布配置檔

php artisan vendor:publish --provider="Mews\Purifier\PurifierServiceProvider"

產生 config/purifier.php,可自訂白名單:

return [
    'encoding' => 'UTF-8',
    'finalize' => true,
    'cachePath' => storage_path('app/purifier'),
    'settings' => [
        'default' => [
            'HTML.Doctype' => 'HTML5',
            'HTML.Allowed' => 'div,b,strong,i,em,u,strike,a[href|title],ul,ol,li,p[style],br,span[style],img[width|height|alt|src],table,thead,tbody,tr,th,td',
            'CSS.AllowedProperties' => 'font,font-size,font-weight,font-style,font-family,text-decoration,color,background-color,text-align',
            'AutoFormat.AutoParagraph' => true,
            'AutoFormat.RemoveEmpty' => true,
        ],
        'custom' => [
            'Attr.EnableID' => true,
        ],
        'youtube' => [
            'HTML.SafeIframe' => true,
            'URI.SafeIframeRegexp' => '%^(https?:)?//(www\.youtube\.com/embed/|player\.vimeo\.com/video/)%',
        ],
    ],
];

使用方式

輔助函數 clean()(全域可用)

$safeHtml = clean($request->input('content')); // 使用 default 設定
$safeHtml = clean($request->input('content'), 'youtube'); // 使用 youtube 設定
$safeHtml = clean($request->input('content'), ['HTML.Allowed' => 'p,b,a[href]']); // 臨時覆蓋

Facade 方式

use Mews\Purifier\Facades\Purifier;

$safeHtml = Purifier::clean($request->input('content'));
$safeHtml = Purifier::clean($request->input('content'), 'custom');

模型存取器自動淨化(推薦)

// App\Models\Article.php
public function setContentAttribute($value)
{
    $this->attributes['content'] = clean($value);
}

// 讀取時若需原始內容,另設 raw_content 欄位或關閉存取器

原生 PHP 防 XSS 函數(無框架/不想裝套件)

function cleanXss(&$string, bool $low = false): bool
{
    if (!is_array($string)) {
        $string = trim($string);
        $string = strip_tags($string); // 移除所有標籤(嚴格模式)
        $string = htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
        if ($low) return true;
        // 進一步過濾危險字元
        $string = str_replace(['"', "\\", "'", "/", "..", "../", "./", "//"], '', $string);
        $string = preg_replace('/%0[0-8bcef]/', '', $string);
        $string = preg_replace('/%1[0-9a-f]/', '', $string);
        $string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $string);
        return true;
    }
    foreach (array_keys($string) as $key) {
        cleanXss($string[$key]);
    }
    return true;
}
⚠️ strip_tags 會移除所有標籤,無法保留安全富文本。生產環境強烈建議用 HTMLPurifier。

纵深防禦清單

  1. 輸入端:表單驗證 + clean() 淨化。
  2. 儲存端:資料庫欄位型別限制、長度限制。
  3. 輸出端:Blade {{ }} 自動轉義、!! 僅用於經 clean() 的內容。
  4. HTTP 標頭:Content-Security-Policy 限制腳本來源、X-Content-Type-Options: nosniff。
  5. Cookie:HttpOnly、Secure、SameSite=Lax。

總結

Laravel 專案防 XSS 標準配置:composer require mews/purifier → 發布配置 → 統一用 clean() 或模型存取器淨化富文本 → Blade 輸出用 {{ }} → 配置 CSP 標頭。零成本、高效能、符合合規要求。

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