02月29, 2012

html2json:一种新的富文本数据传输方案

在这满天由用户创造内容的时代,各个地方穿插着可以让用户输入的入口。如:写文章,写博客等。但由于用户输入的内容完全是不安全的,所以在存储和展现的时候需要对内容进行过滤,避免用户内容产生XSS和钓鱼等各种危害行为。

对于简单的textarea用户输入,过滤起来比较简单,这里不作多的描述。但对于像支持富文本这样的编辑器创造的内容,过滤就没这么简单了。我们先来看下现在的富文本内容从保存到展现是怎么处理的:

1、产品提供富文本编辑器,支持很多很多的功能。(如:文字排版,插入图片、视频,投票,链接等各种格式)

2、用户利用编辑器输入想要的内容

3、提交时获取编辑器里的HTML片段,将HTML片段提交到后端

4、后端拿到HTML片段后对HTML进行解析(一般都是通过C来实现),配置各种过滤规则,对数据进行过滤。

5、将过滤后的数据保存到数据库。

6、展现时从数据库里进行读取内容。

对于数据过滤部分,由于是通过配置规则来进行的,所以局限于我们已经知道的部分。甚至后端人员对浏览器HTML解析不太了解,导致规则并不全。这样随着漏洞的不断发现,小的漏洞可以在展现的时候及时过滤,但对于大的漏洞可能就要重做数据了,这个成本是非常大。

并且这种解决方案不能从根本上解决问题,只能是等外界发现一个漏洞修复一个漏洞,开发人员完全处于被动的状态。如:百度空间的富文本过滤从2006年到现在不知道修复了多少个漏洞了,过滤规则也升级了N多次。

使用JSON的解决方案

随着前后端数据传输越来越多,JSON数据传输标准因此而生了,并且越来越受到开发人员的使用。那我们可不可以通过JSON来传输富文本数据呢?

下面是一种利用JSON进行富文本数据的方案:

1、用户利用富文本编辑器创造内容保存时。

2、不直接将HTML片段传递到后端,而是将HTML片段转化为JSON格式。如:

welefen
转化后的JSON格式为{tag:"div",attr:[], text:"welefen":child:[]}

3、后端收到数据后判断是否是JSON格式(正常传递的肯定是JSON格式,但要对恶意攻击的数据进行处理,如果JSON解析失败,则直接使用HTML转义),然后将JSON数据转化为后端数据对象(如:PHP使用json_decode将JSON数据转化为数组)。

4、对数据对象进行过滤,由于数据格式只有tag,attr,text等,并且这3中数据格式我们都是知道的,如:tag值只有字母和数字组成。所以过滤起来非常简单。

5、将过滤后的数据对象拼合成HTML片段进行保存。

6、展现时直接将保存后的HTML片段展现就可以了。

这种方式一个最大的好处就是数据安全过滤上异常简单,不用使用词法分析,容错处理等各种技术。只用对单片段数据进行数据格式过滤即可。并且性能上也不是问题,几乎可以使用PHP来处理即可,完全不用使用C来进行。

文中提到的html2json, github上有个现成的库,见: https://github.com/Jxck/html2json, 不过将HTML转化为JSON使用的是词法分析,没借用浏览器的Api处理。

对于后端对JSON进行过滤并拼合成HTML片段,还没找到现成的库,找时间自己来写个。

对于富文本数据传输方案,你有什么更好的方案呢?我们一起来探讨


ps: 对于不支持JS的终端,存储的时候对内容直接使用HTML转码,显示的时候直接展示就可以了。

@update 2012.03.05

这种也是有些瑕疵的,主要有:

1、把html转为json会增加要传输的文本大小。一般会增加20%-50%,但数据量也不是很大。

2、文本内容很大时,浏览器将html转为json需要一定的时间。不过不是大问题,测试了下IE6下4W个字符只要400ms,chrome下只要几十毫秒。

所以个人觉得即使有些瑕疵,还是非常值的去使用的。

注:文章内容可修改

本文链接:http://welefen.com/post/html2json-for-rich-content-transfer.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。