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

Yii HTML 淨化器 CHtmlPurifier 完整指南:四大使用場景防範 XSS 攻擊

     編輯:PHP 綜合知識

前言

使用者輸入的 HTML 內容若直接輸出,極易導致 XSS(跨站腳本攻擊)。Yii 內建 CHtmlPurifier 封裝了強大的 HTMLPurifier 函式庫,能依據白名單規則過濾惡意標籤、屬性、CSS、JS 等。本文詳細說明控制器、模型、過濾器、視圖四大使用場景與配置技巧。

核心配置選項

$purifier = new CHtmlPurifier();
$purifier->options = array(
    'URI.AllowedSchemes' => array('http' => true, 'https' => true), // 允許連結協定
    'HTML.Allowed'       => 'div,b,strong,i,em,u,a[href|title],img[src|alt|width|height],p,br,ul,ol,li', // 允許標籤與屬性
    'CSS.AllowedProperties' => 'font,font-size,color,background-color,text-align,margin,padding', // 允許 CSS 屬性
    'AutoFormat.RemoveEmpty' => true, // 移除空標籤
);

場景一:控制器中儲存前淨化

public function actionCreate() {
    $model = new News;
    $purifier = new CHtmlPurifier();
    $purifier->options = array( /* 上述配置 */ );

    if (isset($_POST['News'])) {
        $model->attributes = $_POST['News'];
        // 關鍵:儲存前淨化 content 欄位
        $model->content = $purifier->purify($model->content);
        if ($model->save()) {
            $this->redirect(array('view', 'id' => $model->id));
        }
    }
    $this->render('create', array('model' => $model));
}

場景二:模型 beforeSave() 自動淨化

protected function beforeSave() {
    $purifier = new CHtmlPurifier();
    $purifier->options = array( /* 配置 */ );

    if (parent::beforeSave()) {
        if ($this->isNewRecord) {
            $this->create_date = date('Y-m-d H:i:s');
        }
        // 統一淨化 content
        $this->content = $purifier->purify($this->content);
        return true;
    }
    return false;
}

優點:集中處理,不論從哪個控制器儲存都會生效。

場景三:過濾器中預處理 $_POST

public function filters() {
    return array(
        'accessControl',
        'postOnly + delete',
        'purifier + create', // 僅 create 動作套用
    );
}

public function filterPurifier($filterChain) {
    $purifier = new CHtmlPurifier();
    $purifier->options = array( /* 配置 */ );

    if (isset($_POST['News'])) { // 注意:原文有誤寫 $_POST['news']
        $_POST['News']['content'] = $purifier->purify($_POST['News']['content']);
    }
    $filterChain->run();
}

場景四:視圖中輸出時淨化(Widget 模式)

beginWidget('CHtmlPurifier'); ?>
    
    content; ?>
endWidget(); ?>

適用場景:信任度較低的使用者生成內容(評論、論壇貼文)即時顯示時。

效能優化建議

  1. 快取 Purifier 實例:HTMLPurifier 初始化較重,建議在元件或單例中複用:
    Yii::app()->setComponent('purifier', new CHtmlPurifier($options));
  2. 僅在必要時淨化:儲存時淨化優於輸出時,避免重複運算。
  3. 調整白名單粒度:嚴格限制標籤/屬性,減少解析樹複雜度。

常見誤區

  • ❌ 以為 CHtml::encode() 就足夠 → 它只轉義實體,無法處理「允許部分 HTML」的需求。
  • ❌ 直接使用 strip_tags() → 無法防禦屬性型 XSS(如 onclick、style="expression(...)")。
  • ❌ 配置 'HTML.Allowed' => 'div' 過於寬鬆 → 應明確列出允許的標籤與屬性白名單。

相關專題推薦

正確使用 CHtmlPurifier 是 Yii 專案防範 XSS 的關鍵一環。根據業務場景選擇四大使用方式之一,並嚴格維護白名單配置,即可在保留豐富文字編輯功能的同時,構建安全的輸出防線。

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