Heim  >  Artikel  >  Backend-Entwicklung  >  我觉得写的代码98%都是操作字符串的,关心的问题就是字符串从哪儿来,然后把它保存到哪儿去,然后怎么显示给用户

我觉得写的代码98%都是操作字符串的,关心的问题就是字符串从哪儿来,然后把它保存到哪儿去,然后怎么显示给用户

WBOY
WBOYOriginal
2016-06-06 20:22:511038Durchsuche

我觉得写的代码98%都是操作字符串的,关心的问题就是字符串从哪儿来,然后把它保存到哪儿去,然后怎么显示给用户,所以我问个数据保存的问题,在数据库中怎么保存呢?

现在的动态网站,“动态内容”已经离不开html了, 而html来自于用户又会不安全,给我们防护造成困难,而如果使用“不给用户提供富文本编辑器”那整个网站出来模板内容以外,其它的内容除了文本就是文本,文章中没有图片,没有样式,清一色的文本,所以我们还是要依赖于富文本。

可是现在我有一个疑问,比如一个文章表tb_article(id,name,content),我们允许用户发布带有图片视频等媒体的文章,那么现在我有一个疑问:

用户post过来的内容是什么我们不管,我们服务器怎么处理这些数据,然后在数据库中该怎么保存呢?

我们假定一篇文章名可以为:<script>alert(1)<script></script>嘻嘻嘻 ,总之我们不会限制用户不能输入,不能保存什么。

thinkphpI()函数默认使用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>嘻嘻嘻 ,总之我们不会限制用户不能输入,不能保存什么。

thinkphpI()函数默认使用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,数据库里面保存的和用户输入时的不一致,这样好吗?

  1. 用户看不到你是怎么存储他的消息的

  2. 你在给用户展示时, 只要你不要再过滤一遍html tags就可以让用户无感知的观察到& 而不是&

  3. 病从口入。

  4. 如果你系统足够强大,或者,你根本不在乎xss,你完全可以不用提这个问题的。

你需要htmlpurifier

数据库里存储的应该是用户输入的原始内容,否则用户重新编辑的时候怎么处理?
PHP输出页面时用htmlspecialchars把特殊字符(&amp;amp;amp;,",',)替换为HTML实体(&amp;amp;amp;"'<>).注意,前端JS用innerHTML往页面输出HTML时也要执行类似PHP的htmlspecialchars转换,因为经过JS赋值后,Unicode字符\u003c和\u003e被转换成,而PHP的htmlspecialchars并没有处理\u003c和\u003e.

&amp;amp;amp;lt;code&amp;amp;amp;gt;function htmlspecialchars(str) {
    var map = {
        '&amp;amp;amp;amp;': '&amp;amp;amp;amp;',
        '&amp;amp;amp;quot;']/g, function(m) { return map[m]; });
}&amp;amp;amp;lt;/code&amp;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测试

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn