HTML Purifier解决XSS问题

基本用法

默认下,使用UTF-8编码,和XHTML 1.0 Transitional文档类型.

require_once '/path/to/HTMLPurifier.auto.php';
$config = HTMLPurifier_Config::createDefault();
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify($dirty_html);

使用配置

详细的配置规则:http://htmlpurifier.org/live/configdoc/plain.html

$config->set('HTML.AllowedElements', array('div'=>true, 'table'=>true, 'tr'=>true, 'td'=>true, 'br'=>true));
$config->set('HTML.Doctype', 'XHTML 1.0 Transitional')       //html文档类型(常设)
$config->set('Core.Encoding', 'UTF-8')           //字符编码(常设)

HTML允许的元素:div元素,table元素,tr元素,td元素,br元素

1、配置属性选择

HTMLPurifier的配置文档主要是两级分类,大类分Attr(属性)、HTML(html标签)、AutoFormat(自动格式)、CSS(css配置)、Output(输出配置)……小类选择通过大类名称加.加小类名称可以完成。

比如我要配置允许的html标签,比如说p标签和a标签,可以如下配置

$config->set('HTML.Allowed', 'p,a');

2、属性值的选择

在官方文档中,点击一个属性后,可以看到对这个属性的解释,会告诉你这个属性的值的类型(Type)是String、Int、Array、Boolen……

接着还会告诉你这个属性的默认值,比如是NULL还是true还是false等。这个值的格式就跟PHP的格式一样的。

3、白名单过滤机制

HTMLPurifier使用了白名单过滤机制,只有被设置允许的才会通过检验。

4、基本过滤事例

a、过滤掉文本中的所有html标签

/**
 * 过滤掉所有html标签很简单,原因则在白名单机制完成
 */
$config->set('HTML.Allowed', '');

b、保留超链接标签a及其href链接地址属性,并自动添加target属性值为’_blank’

$config->set('HTML.Allowed', 'a[href]');
$config->set('HTML.TargetBlank', true);
/**
 * 只允许图片标签 img 及其链接和描述
 */
$config->set('HTML.Allowed', 'img[src|alt]');

c、自动完成段落代码并清除掉无用的空标签

// 让文本自动添加段落标签,前提是必须允许P标签的使用
$config->set('HTML.Allowed', 'p');
$config->set('AutoFormat.AutoParagraph', true);
// 清除空标签
$config->set('AutoFormat.RemoveEmpty', true);

当然了,HTMLPurifier的过滤功能非常强大的,每一个点都要写到那也不现实,这里主要还是要说明如何写配置,只有配置好了才知道如何去拓展!

 

实例

1.id规则

默认下,HTML Purifier是不允许使用id的,可以通过Attr.EnableID选项来控制,当允许使用id的时候,有点需要注意,id只允许全局一个,后面重复的都会被去掉。

$config->set('Attr.EnableID', true); // 允许使用id  
$config->set('Attr.IDPrefix', 'test_'); // 给所有id加上前缀test_  
$config->set('Attr.IDBlacklist', array( // 设置黑名单,会过滤掉设置的id,如果设置了id前缀,要把前缀也加上  
    'test_black_list'  
));  
$config->set('Attr.IDBlacklistRegexp', '/list_\d+/'); // 黑名单,使用正则匹配 

输入:

<a id="test_by_willko" href="aa">adf</a>  
<a id="black_list" href="aa">adf</a>  
<a id="black_list_2" href="aa">adf</a> 

输出:

    <a id="test_by_willko" href="aa">adf</a>  
    <a href="aa">adf</a>  
    <a href="aa">adf</a>  

2.class规则

默认下,是允许所有的class。属性Attr.AllowedClasses用于设置允许的class名,没被设置的class将被拒绝使用。而Attr.ForbiddenClasses则用于设置拒绝使用的class名。

    $config->set('Attr.AllowedClasses', array( // 设置允许使用的class名  
        'test_by_willko'  
    ));  
    $config->set('Attr.ForbiddenClasses', array( // 设置拒绝使用的class名  
        'ignore'  
    ));  

#### 自定义标签和属性 ####

    // 默认配置
    $config = HTMLPurifier_Config::createDefault();

    //设置配置的名称
    $config->set('HTML.DefinitionID', 'smzdm library version');
    //设置配置的版本
    $config->set('HTML.DefinitionRev', 1);
    // 清理配置缓存,上线时关掉这句
    $config->set('Cache.DefinitionImpl', null);

    $def = $config->getHTMLDefinition(true);
    // 允许 audio 标签
    $def->addElement(
        'audio',
        'Block',
        'Flow',
        'Common',
        [
            'data-id' => 'Number'
        ]
    );
    // 为 img 标签添加 data-weight 属性
    $def->addAttribute(
        'img',
        'data-weight',
        'Number'
    );

    $this->html_purifier = new HTMLPurifier($config);

这里多了3个set操作,配置的**名称和版本**会作为配置的缓存key,最终这份配置会被缓存到磁盘到一个文件里。但是如果先执行过一次生成了缓存,而后再次执行时修改了配置,这个缓存是不会更新的,因此上面的第三个set就是清理缓存的用途,上线时就不要保留了,只是在调试htmlpurifier 时保障每次配置都可以得到更新而已。
下面的两个地方分别定义了一个 audio 标签和 为 img 标签添加的新属性
如果有比较多的配置、标签、属性需要进行设置的也可以自己封装一个方法来设置。

高级应用

http://htmlpurifier.org/docs/enduser-customize.html

自定义一个类 HtmlPurifier.php

    <?php  
    require_once 'HTMLPurifier.includes.php';  
    require_once 'HTMLPurifier.autoload.php';  
    class Resume_HtmlPurifier implements Zend_Filter_Interface{  
        protected $_htmlPurifier = null;  
        public function __construct($options = null)  
        {  
            $config = HTMLPurifier_Config::createDefault();  
            $config->set('Code.Encoding', 'UTF-8');    
            $config->set('HTML.Doctype', 'XHTML 1.0 Transitional')  
            if(!is_null($options)){  
                foreach($options as $option){  
                    $config->set($option[0], $option[1], $option[2]);  
                }  
            }  
            $this->_htmlPurifier = new HTMLPurifier($config);  
        }  
        public function filter($value)  
        {  
        return $this->_htmlPurifier->purify($value);  
      
       
        }  
    }  
    ?>  

设置config信息

例如:

    $conf = array(  
        array('HTML.AllowedElements',  
                    array(  
                            'div' => true,  
                            'table' => true,  
                            'tr' => true,  
                            'td' => true,  
                            'br' => true,  
                        ),  
                        false), //允许属性 div table tr td br元素  
             array('HTML.AllowedAttributes', array('class' => TRUE), false),     //允许属性 class  
             array('Attr.ForbiddenClasses', array('resume_p' => TRUE), false),   //禁止classes如  
             array('AutoFormat.RemoveEmpty', true, false),              //去空格  
             array('AutoFormat.RemoveEmpty.RemoveNbsp', true, false),       //去nbsp  
             array('URI.Disable', true, false),  
    );  

调用

    $p = new Resume_HtmlPurifier($conf);  
    $puri_html = $p->filter($html);  

 

 

参考资料:

http://blog.csdn.net/hanzengyi/article/details/43019479

http://willko.iteye.com/blog/475493

http://blog.csdn.net/motian06/article/details/8064811

http://blog.csdn.net/u010128133/article/details/73823367

转载于:https://my.oschina.net/u/1269381/blog/1536752

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值