一个安全方面的问题 qiang

除了 教程里说的


<?php $this->beginWidget('CHtmlPurifier'); ?>

...display user-entered content here...

<?php $this->endWidget(); ?>

还有什么更有效的方法 免疫这个问题(XSS)?

最好从数据层过滤

能不能给个建议 教程里说的方法 太麻烦了 我要所有地方都加上这个东西

还是能在数据层过滤替换掉最好

CHtmlPurifier可以作为filters使用,但是现在还没找到怎么用。

我自己的想法是写一个Component,放到config里面。这样以后就可以用yii::app()->html->format(…);

add at 2009-09-11 09:27:20 :

内置的HTML Purifier是最好的解决方案,这是测试效果:

http://htmlpurifier.org/live/smoketests/xssAttacks.php

这两个扩展或许能给你一些idea:

http://www.yiiframework.com/extension/yxss-filter/

http://www.yiiframework.com/extension/esanitizer/

我个人的观点是尽量避免对用户的输入进行过滤,而把过滤留到显示的时候进行。

为什么尽量避免对用户的输入进行过滤,而把过滤留到显示的时候进行?

过滤过程是不可逆的,容易造成数据丢失。比如,你今天使用了一个有缺陷的过滤器,把有用的东西给过滤掉了,明天你升级过滤器了,可是原始数据已经不完整了。

通常只有以HTML形式显示的数据才需要过滤。这种数据在每个页面一般只有少数几个(通常用于显示大段的HTML内容)。所以在显示时再过滤程序上并不麻烦。你也可以考虑定义一个快捷函数来简化过滤过程:




function purify($content)

{

    static $purifier;

    if($purifier===null)

        $purifier=new CHtmlPurifier;

    return $purifier->purify($content);

}



比如一个BLOG系统,对于用户名、Email等文本型的数据,过滤之后存储就可以了。对于大段的HTML,显示的时候进行过滤。

谢谢qiang!

学习了

其实用户名和email都用不着过滤,因为你应该有validator确保它们的格式是符合你的要求的。

另外,在显示非HTML的文本型数据时,必须进行HTML编码:CHtml::encode($text)。这样就可以确保安全了。

学习了,正需要

把过滤留到显示的时候进行,会不会影响效率?听说CHtmlPurifier很占资源。

你可以添加一个额外的字段,用来保存过滤过的内容。

这样冗余太高了吧

一般来说,"文章正文"会占用很大字节数,也是数据库中占空间最多的字段,如果用一个额外的字段来保存过滤过的文章正文,那数据库空间占用差不多会增加一倍吧。

这个冗余的确很高。如果数据库空间是问题的话,你可以考虑覆盖原始内容。