HtmlAttributeFilter 解析 HTML 字串,移除不在白名單中的標籤屬性,防範 XSS 攻擊,同時保留必要屬性(如 id、class、href)。支援標籤級例外規則與忽略標籤清單。
<?php
class HtmlAttributeFilter {
private $_str = '';
private $_allow = []; // 全域允許屬性:['id','class','title']
private $_exception = []; // 標籤例外:['a' => ['href','class'], 'img' => ['src','alt']]
private $_ignore = []; // 忽略過濾標籤:['script','style']
public function strip($str) { /* 主入口 */ }
public function setAllow(array $allow) { $this->_allow = $allow; }
public function setException(array $exc) { $this->_exception = $exc; }
public function setIgnore(array $ignore) { $this->_ignore = $ignore; }
private function findElements() { /* 正則提取所有標籤 */ }
private function findAttributes($nodes) { /* 解析屬性 name="value" */ }
private function removeAttributes($nodes) { /* 依白名單/例外決定保留/移除 */ }
private function isException($tag, $attr) { /* 判斷是否例外 */ }
private function createAttributes($node) { /* 重組安全屬性字串 */ }
private function protect($str) { /* 特殊字元轉義 */ }
}
$filter = new HtmlAttributeFilter();
$filter->setAllow(['id', 'class', 'style']);
$filter->setException([
'a' => ['href', 'title', 'target'],
'img' => ['src', 'alt', 'width', 'height'],
'input' => ['type', 'value', 'name']
]);
$filter->setIgnore(['script', 'style']); // 完全不處理
$html = '<div id="main" onclick="alert(1)"><a href="/link" onmouseover="xss()">Link</a></div>';
$safe = $filter->strip($html);
// 結果:<div id="main"><a href="/link">Link</a></div>
preg_match_all 分兩階段提取「標籤」與「屬性」,避免單一複雜正則難以維護。protect 機制)。script、style 等敏感標籤直接跳過,避免破壞內容或誤判。strip_tags 或 HTMLPurifier 使用。> 等),高安全需求場景請改用 HTMLPurifier。htmlspecialchars 雙重防護。HtmlAttributeFilter 以白名單機制精準控制 HTML 屬性,適合「信任標籤結構、僅需清理屬性」的中低風險場景(如 CMS 後台內容儲存前預處理)。高風險場景(使用者任意 HTML 輸入)務必採用完整 HTML 淨化庫。