Rumah >pembangunan bahagian belakang >tutorial php >我觉得写的代码98%都是操作字符串的,关心的问题就是字符串从哪儿来,然后把它保存到哪儿去,然后怎么显示给用户
我觉得写的代码98%都是操作字符串的,关心的问题就是字符串从哪儿来,然后把它保存到哪儿去,然后怎么显示给用户,所以我问个数据保存的问题,在数据库中怎么保存呢?
现在的动态网站,“动态内容”已经离不开html了, 而html来自于用户又会不安全,给我们防护造成困难,而如果使用“不给用户提供富文本编辑器”那整个网站出来模板内容以外,其它的内容除了文本就是文本,文章中没有图片,没有样式,清一色的文本,所以我们还是要依赖于富文本。
可是现在我有一个疑问,比如一个文章表tb_article(id,name,content),我们允许用户发布带有图片视频等媒体的文章,那么现在我有一个疑问:
用户post过来的内容是什么我们不管,我们服务器怎么处理这些数据,然后在数据库中该怎么保存呢?
我们假定一篇文章名可以为:<script>alert(1)<script></script>
嘻嘻嘻 ,总之我们不会限制用户不能输入,不能保存什么。
thinkphp
中I()
函数默认使用htmlspecialchars
(默认不处理单引号)对数据进行处理,将数据进行html实体编码,如果这样保存到数据库好吗?用户输入的明明是&
而保存在数据库里面的却是&amp
,数据库里面保存的和用户输入时的不一致,这样好吗?
而文章内容富文本post过来的很可能是html内容,比如<img src="1.png" alt="我觉得写的代码98%都是操作字符串的,关心的问题就是字符串从哪儿来,然后把它保存到哪儿去,然后怎么显示给用户" >
,如果进行html实体编码后保存到数据库的话,在读出来的话,文章内容就不是一张图片了,而是看得见摸得着的纯文本<img src="1.png" alt="我觉得写的代码98%都是操作字符串的,关心的问题就是字符串从哪儿来,然后把它保存到哪儿去,然后怎么显示给用户" >
了,所以这种情况该如何考虑呢?难道输出时在进行htmlspecialchars_decode
重新解码吗,那这样每次查询文章就要解码一次不会有性能问题吗,每次这样做感觉笨笨的。
我都不知道到底怎么样才是最好的,wordpress,DZ,他们是怎么做的呢?
像一些笔记应用,有道云笔记等又是怎么做的呢?
还是要分不同情况对待?
希望有经验的大神指点一下,谢谢了。
已有类似的问题:
http://segmentfault.com/q/1010000004067521
这个问题已被关闭,原因:与已有问题重复
我觉得写的代码98%都是操作字符串的,关心的问题就是字符串从哪儿来,然后把它保存到哪儿去,然后怎么显示给用户,所以我问个数据保存的问题,在数据库中怎么保存呢?
现在的动态网站,“动态内容”已经离不开html了, 而html来自于用户又会不安全,给我们防护造成困难,而如果使用“不给用户提供富文本编辑器”那整个网站出来模板内容以外,其它的内容除了文本就是文本,文章中没有图片,没有样式,清一色的文本,所以我们还是要依赖于富文本。
可是现在我有一个疑问,比如一个文章表tb_article(id,name,content),我们允许用户发布带有图片视频等媒体的文章,那么现在我有一个疑问:
用户post过来的内容是什么我们不管,我们服务器怎么处理这些数据,然后在数据库中该怎么保存呢?
我们假定一篇文章名可以为:<script>alert(1)<script></script>
嘻嘻嘻 ,总之我们不会限制用户不能输入,不能保存什么。
thinkphp
中I()
函数默认使用htmlspecialchars
(默认不处理单引号)对数据进行处理,将数据进行html实体编码,如果这样保存到数据库好吗?用户输入的明明是&
而保存在数据库里面的却是&amp
,数据库里面保存的和用户输入时的不一致,这样好吗?
而文章内容富文本post过来的很可能是html内容,比如<img src="1.png" alt="我觉得写的代码98%都是操作字符串的,关心的问题就是字符串从哪儿来,然后把它保存到哪儿去,然后怎么显示给用户" >
,如果进行html实体编码后保存到数据库的话,在读出来的话,文章内容就不是一张图片了,而是看得见摸得着的纯文本<img src="1.png" alt="我觉得写的代码98%都是操作字符串的,关心的问题就是字符串从哪儿来,然后把它保存到哪儿去,然后怎么显示给用户" >
了,所以这种情况该如何考虑呢?难道输出时在进行htmlspecialchars_decode
重新解码吗,那这样每次查询文章就要解码一次不会有性能问题吗,每次这样做感觉笨笨的。
我都不知道到底怎么样才是最好的,wordpress,DZ,他们是怎么做的呢?
像一些笔记应用,有道云笔记等又是怎么做的呢?
还是要分不同情况对待?
希望有经验的大神指点一下,谢谢了。
已有类似的问题:
http://segmentfault.com/q/1010000004067521
保存的时候主要防注入,展示的时候才需要防XSS。
像标题这种铁定纯文本的东西你就直接htmlentities
或者htmlspecialchars
过滤。正文如果要支持富文本你还需要过滤script等敏感标签。一般有白名单标签过滤和黑名单标签过滤两种。
不过还存在别人用\uxxxx
字符串绕过htmlspecialchars
过滤的问题。
关于你关注的性能问题,很容易用Cache解决,不必太担心。尽量在数据库里保存原始数据,在展示的环节解决XSS问题,如果过滤代码升级了,直接Flush掉Cache就行了。
另外针对现代浏览器你还可以使用CSP声明信任的script等资源域名白名单。
编码呀同学~~
你的问题可以转换为:如何防御XSS攻击
用户输入的明明是&而保存在数据库里面的却是&amp,数据库里面保存的和用户输入时的不一致,这样好吗?
用户看不到你是怎么存储他的消息的
你在给用户展示时, 只要你不要再过滤一遍html tags就可以让用户无感知的观察到& 而不是&
病从口入。
如果你系统足够强大,或者,你根本不在乎xss,你完全可以不用提这个问题的。
你需要htmlpurifier
数据库里存储的应该是用户输入的原始内容,否则用户重新编辑的时候怎么处理?
PHP输出页面时用htmlspecialchars把特殊字符(&,",',
)替换为HTML实体(&amp;amp;"'<>
).注意,前端JS用innerHTML往页面输出HTML时也要执行类似PHP的htmlspecialchars转换,因为经过JS赋值后,Unicode字符\u003c和\u003e被转换成,而PHP的htmlspecialchars并没有处理\u003c和\u003e.
&amp;amp;lt;code&amp;amp;gt;function htmlspecialchars(str) { var map = { '&amp;amp;amp;': '&amp;amp;amp;', '&amp;amp;quot;']/g, function(m) { return map[m]; }); }&amp;amp;lt;/code&amp;amp;gt;
关于HTML标签的支持,比如允许用户输入超链接:[url=http://www.php.net]PHP[/url]
页面输出时,先用htmlspecialchars过滤,然后用正则匹配拿到[url]这对标签,转换成:<a href="http://www.php.net">PHP</a>
然后经过HTMLPurifier过滤XSS后输出,因为http://www.php.net
这个地方存在XSS注入风险,比如填的是[url=javascript:alert(String.fromCharCode(88,83,83))]PHP[/url]
如果不经HTMLPurifier过滤,就会产生XSS注入.
XSS测试