根据HTML标签,属性来进行过滤的类,用于安全处理用户的富文本
在用户前台应用了富文本编辑器,这就使得HTML输出时面临XSS等危险代码的风险。为了解决这个问题,互联网上有很多正则替换的方法,但是都不是很保险且扩展性不高。
后来我在代码仓库中找到了Kses类,这是一个可以根据HTML标签,属性来进行过滤的类,修改了一下就可以适配THINKPHP了。
Kses的版权和相关协议归原作者所有。
-----------------------我是华丽丽的分割线---------------------------
Kses大家应该都不陌生,wordpress的富文本内容的过滤应用的就是这个东西。它的安全性还是可以保障的(如果有漏洞希望大家也反馈反馈!,我没进行具体的测试)
我修改后的类文件需要PHP5+THINKPHP3.2环境,如果你不是,请根据源文件和我的修改说明二次开发即可(原作者提供了PHP4的版本....)
下面我只讲解一下常用的方法,更多的方法可以参考附件里面的原作者提供的文档(是英文)。
首先,在配置文件中加入KSES_ALLOWED_PROTOCOL,KSES_ALLOWED_HTML,KSES_ALLOWED_GLOBAL_ATTR元素,他们的意义分别为:允许的协议,允许的HTML元素及其属性,和允许的全局属性。
下面举个例子:
第一,我们允许用户在富文本中使用p元素和a元素,并且p元素不允许使用任何属性,a元素只允许使用href、name和target属性,我们在KSES_ALLOWED_HTML这么写:
'KSES_ALLOWED_HTML' => array(
'p' => array(),
'a' => array(
'href' => true,
'name' => true,
'target' => true,
))
第二,我们允许用户在富文本中使用http、ftp和mailto连接协议,比如在a元素的href和img元素的src,我们在KSES_ALLOWED_PROTOCOL这么写:
'KSES_ALLOWED_PROTOCOL' => array(
'http',
'ftp',
'mailto',
))
第三(可选),我们允许用户在富文本中所有HTML元素里使用title,style属性(这回覆盖我们设置的第一个步骤),我们可以在KSES_ALLOWED_GLOBAL_ATTR里这么写:
'KSES_ALLOWED_GLOBAL_ATTR'=>array(
'style' => true,
'title' => true,
),
然后我们在需要执行HTML过滤的地方实例化Kses类
命名空间(这个可能每个人不一样):
use Common\Api\Kses;
然后实例化,使用Parse方法
类似下面这个样子:
$kses = new kses;
exit($kses->Parse('<p style="text-align: center;">
<a href="http://www.baidu.com">测试</a>
</p>'));
那么如果我们是按照上面3步来设置的,最终会输出
<p style="text-align: center;">
<a href="http://www.baidu.com">测试</a>
</p>
’
有人问为什么p元素支持style属性,请看第三步
-----------------------我是华丽丽的分割线---------------------------
上面是一个全部通过过滤的例子,再举几个不通过的。
如果我们的代码为
<p style2="text-align: center;">
<a href="http://www.baidu.com">测试</a>
</p>
那么style2连同后面都会被过滤掉,因为P元素和全局都没有设置允许使用style2属性。
如果我们代码:
<img src="http://1.cc/1.jpg" />
整个img元素会被过滤掉,因为我们没有允许使用img元素(请看第一步)
附加!!全局属性请注意:
如果全局属性允许了style,那么系统只允许使用部分安全的CSS属性,比如上面的text-align就可以,但text-align2就不可以了。具体的这个项目在类文件的safecss_filter_attr方法,我已经内置了常用的CSS属性,如果需要扩展请自行修改。
比如我们写代码
<p style="text-align2: center;">
<a href="http://www.baidu.com">测试</a>
</p>
那么text-align2这个会被过滤掉
-----------------------我是华丽丽的分割线---------------------------
其实Kses还支持很多功能,比如还可以限制某个HTML元素属性填写多少字符的内容,更多的方法请参考附件中Kses的手册。
下面说一下我在类中修改了那些内容,我是从oop/php5.class.kses中修改过来的,只支持PHP5 + THINKPHP3.2哦!
修改日志 ( 2014-4-13 )
1. 增加命名空间,和配置等以适应THINKPHP
2. 修改类名。
3. 2014-4-13 01:21:01 修正参数名称BUG一个。
4. 增加了全局属性,以及CSS检测(也就是例子中的步骤三实现的功能)
大家注意看第三条,这是原作者版本中诡异的拼写错误,在oop/php5.class.kses的958行中,请把string2参数换成string。
我在附件中提供的原版是没有修改这个BUG的(THINKPHP适配版本肯定已经修改了),所以如果你要看原版演示,先把这个拼写错误修复了。
-----------------------我是华丽丽的分割线---------------------------
如果有什么问题大家可以再问!谢谢
我貌似在讨论区发了重贴,但是THINK不提供删除什么的..抱歉了
2014年4月14日 16:48:22:增加常用HTML元素和节点配置文件(仅供参考)
Kses-2014年4月14日 16-47-更新.zip
( 62.61 KB 下载:67 次 )