500行PHP代碼搞定富文本安全過濾

繼上2篇文章講到利用JSON這種格式化的數據進行傳輸,后端只要差不多500行左右的PHP代碼就搞定了整個富文本安全過濾。由于每個編輯器支持的功能不同,所以對應的后端過濾策略也不同。本文詳細介紹下如果通過配置使用json2html達到你所需要的過濾效果。

由于安全漏洞是無窮無盡的,所以使用黑名單的方式肯定不能杜絕所有的安全漏洞。json2html完全是利用白名單的方式,一切不在白名單之類的內容都將會被過濾掉,從而保證過濾后的數據是安全的。

使用方法

require_once '../src/json2html.class.php';
     $json = "json content";
     $instance = new JSON2HTML($json, $options);
    //$instance->xxx 設置各種白名單 
    //獲取過濾后的結果
    $result = $instance->run();

配置選項$options

public $options = array (
     "checkTag" => true, //是否檢測tag
     "checkAttr" => true, //是否檢測屬性名
     "filterAttrValue" => true, //是否過濾屬性值
     "escapeHtml" => true, //是否進行html轉碼
     "tagAttrRequired" => true, //標簽必須包含的屬性
     "tagChildRequired" => true, //標簽必須包含的子元素
     );

過濾規則和接口

1、標簽白名單

默認配置白名單:

public $tagBlankList = array (
     "a", "span", "img", "p", "br",
     "div", "strong", "b", "ul", "li", "ol", "embed","object","param", "u"
     );

可以通過下面的方法添加和移除標簽白名單:

$instance->addTagBlank($tag); //$tag可以是單個標簽名,也可以是多個標簽名組成的數組
    $instance->addTagBlank("em"); //增加em標簽
    $instance->addTagBlank(array("em", "pre", "h1")); //增加em,pre,h1標簽
    $instance->removeTagBlank("em");// 移除em標簽
    $instance->removeTagBlank(array("em", "pre")); //移除em,pre標簽

2、標簽屬性名白名單

默認配置白名單:

public $attrBlankList = array (
     "*" => array ("id", "class", "name", "style", "value" ),
     "a" => array ("href", "title" ),
     "img" => array ("width", "src", "height", "alt" ),
     "embed" => array("width", "height", "allowscriptaccess", "type", "src"),
     "param" => array("allowscriptaccess"),
     );

可以通過下面的方法添加和移除標簽屬性白名單:

$instance->addAttrBlank($attr, $tag); //$attr可以是字符串或者數組
    $instance->addAttrBlank("title", "*"); //給所有的標簽加上title屬性
    $instance->addAttrBlank("_target", "a"); //給a標簽增加_target屬性
    $instance->addAttrBlank(array("_target", "rel"), "a"); //給a標簽增加_target和rel屬性
    $instance->removeAttrBlank("_target"); //移除所有標簽的_target屬性

3、標簽屬性值每個過濾規則

由于每個標簽屬性值過濾規則可能都不一樣,所以是通過方法的方式進行,如:

protected function _filterSrcAttrValue($value = '', $tag = ''); //src值的過濾規則
    protected function _filterHrefAttrValue($value = '', $tag = '') ; //href值的過濾規則
    protected function _filterStyleAttrValue($value = '', $tag = '') ; //style值的過濾規則

如果需要擴展的話,可以通過一個類繼承json2html類來實現,如:

class myEdito extends json2html{
        protected function _fitlerTitleAttrValue($value, $tag) //過濾title規則
    }

4、標簽里必須含有某些屬性和值規則

有些標簽必須含有某些屬性,并且屬性值是我們給定的,系統默認屬性如下:

public $tagAttrRequired = array (
     "embed" => array (
     "allowscriptaccess" => "never",
     "type" => "application/x-shockwave-flash"
     ),
     );

表示embed標簽含有allowscriptaccess和type屬性,并且值也是我們給定的,如果要過濾的JSON文本里含有這樣的屬性,也會被我們給定的值覆蓋。

可以通過下面的方法增加或移除標簽必須含有的屬性和值:

$instance->addTagAttrRequired($attrs = array(), $tag);
    $instance->removeTagAttrRequired($attrs = array(), $tag);

5、標簽包含的子標簽必須包含某些屬性和值規則

相對于有些標簽必須含有某些屬性和值,有些標簽必須含有特定的子標簽,并且子標簽必須含有某些屬性和值,如:object標簽

系統默認配置如下:

public $tagChildRequired = array(
     "object" => array(
     /**
     * object里必須包含param,并且是指定的屬性,如果有這個子標簽但屬性值不一致,則覆蓋掉
     */
     "param" => array(
     array("where" => array("name" => "allowscriptaccess"), "value"=> array("value" => "never")),
     )
     )
     );

表示object標簽必須含有param標簽,并且查詢到name="allowscriptaccess"里,并且有value="never"。

6、style屬性值檢測規則

style屬性值對應的css文本需要進行過濾,系統默認配置如下:

public $styleValueBlankList = array (
     'font-family' => "/^(.){2,20}$/",
     'font-size' => "/^\d+[a-z]{2,5}$/",
     "color" => "/^(rgb\s*\(\d+\s*,\s*\d+\s*,\s*\d+\))|(\#[0-9a-f]{6})$/",
     "text-align" => array("left", "right", "center"),
     "background-color" => "/^(rgb\s*\(\d+\s*,\s*\d+\s*,\s*\d+\))|(\#[0-9a-f]{6})$/",
     );

可以通過下面的方法添加或者移除style屬性值檢測規則:

$instance->addStyleValueBlank($cssAttr, $value); //$value可以是正則,也可以是數組。
    $instance->removeStyleValueBlank($cssAttr);

以上就是所有json2html的配置選項了,你可以通過配置選項打造你自己的富文本過濾規則。

項目地址:https://github.com/welefen/html2json


所屬標簽

無標簽

25选5玩法中奖