使用者輸入的 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));
}
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;
}
優點:集中處理,不論從哪個控制器儲存都會生效。
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();
}
beginWidget('CHtmlPurifier'); ?>
content; ?>
endWidget(); ?>
適用場景:信任度較低的使用者生成內容(評論、論壇貼文)即時顯示時。
Yii::app()->setComponent('purifier', new CHtmlPurifier($options));CHtml::encode() 就足夠 → 它只轉義實體,無法處理「允許部分 HTML」的需求。strip_tags() → 無法防禦屬性型 XSS(如 onclick、style="expression(...)")。'HTML.Allowed' => 'div' 過於寬鬆 → 應明確列出允許的標籤與屬性白名單。正確使用 CHtmlPurifier 是 Yii 專案防範 XSS 的關鍵一環。根據業務場景選擇四大使用方式之一,並嚴格維護白名單配置,即可在保留豐富文字編輯功能的同時,構建安全的輸出防線。