基于NodeJS的前后端分离的思考与实践(四)安全

在前后端分离的开发模式中,从开发的角色和职能上来讲,一个最明显的变化就是:以往传统中,只负责浏览器环境中开发的前端同学,需要涉猎到服务端层面,编写服务端代码。而摆在面前的一个基础性问题就是如何保障Web安全?

本文就在前后端分离模式的架构下,针对前端在Web开发中,所遇到的安全问题以及应对措施和注意事项,并提出解决方案。

跨站脚本攻击(XSS)的防御

问题及解决思路

跨站脚本攻击(XSS,Cross-site scripting)是最常见和基本的攻击Web网站的方法。攻击者可以在网页上发布包含攻击性代码的数据,当浏览者看到此网页时,特定的脚本就会以浏览者用户的身份和权限来执行。通过XSS可以比较容易地修改用户数据、窃取用户信息以及造成其它类型的攻击,例如:CSRF攻击。

预防XSS攻击的基本方法是:确保任何被输出到HTML页面中的数据以HTML的方式进行转义(HTML escape)。例如下面的模板代码:

复制代码 代码如下:


<textarea>$description</textarea>

这段代码中的$description为模板的变量(不同模板中定义的变量语法不同,这里只是示意一下),由用户提交的数据,那么攻击者可以输入一段包含”JavaScript”的代码,使得上述模板语句的结果变成如下的结果:

复制代码 代码如下:


<textarea>
</textarea><script>alert('hello')'</script>
</textarea>

上述代码,在浏览器中渲染,将会执行JavaScript代码并在屏幕上alert hello。当然这个代码是无害的,但攻击者完全可以创建一个JavaScript来修改用户资料或者窃取cookie数据。

解决方法很简单,就是将$description的值进行html escape,转义后的输出代码如下

复制代码 代码如下:


<textarea>
&lt;/textarea&gt;&lt;script&gt;alert(&quot;hello!&quot;)&lt;/script&gt;
</textarea>

以上经过转义后的HTML代码是没有任何危害的。

Midway的解决方案

转义页面中所有用户输出的数据

对数据进行转义有以下几种情况和方法:

1. 使用模板内部提供的机制进行转义

中途岛内部使用KISSY xtemplate作为模板语言。

在xtemplate实现中,语法上使用两个中括号( {{val}})解析模板数据, ,默认既是对数据进行HTML转义的,所以开发者可以这样写模板:

复制代码 代码如下:


<textarea>{{description}}</textarea>

在xtemplate中,如果不希望输出的数据被转义,需要使用三个中括号({{{val}}})。

2. 在Midway中明确的调用转义函数

开发者可以在Node.js程序或者模板中,直接调用Midway提供的HTML转义方法,显示的对数据进行转义,如下:

方法1:在Node.js程序中对数据进行HTML转义

复制代码 代码如下:


var Security= require('midway-security');
//data from server,eg {html:'</textarea>',other:""}
data.html =Security.escapeHtml(data.html);
xtpl = xtpl.render(data);

方法2:在模板中对HTML数据进行HTML转义

复制代码 代码如下:


<textarea>Security.escapeHtml({{{description}}})</textarea>

注意:只有当模板内部没有对数据进行转义的时候才使用Security.escapeHtml进行转义。 否则,模板内部和程序会两次转义叠加,导致不符合预期的输出。

推荐:如果使用xtemplate,建议直接使用模板内置的{{}}进行转义; 如果使用其他模板,建议使用Security.escapeHtml进行转义。

过滤页面中用户输出的富文本

你可能会想到:“其实我就是想输出富文本,比如一些留言板、论坛给用户提供一些简单的字体大小、颜色、背景等功能,那么我该如何处理这样的富文本来防止XSS呢?”

1. 使用Midway中Security提供的richText函数

Midway中提供了richText方法,专门用来过滤富文本,防止XSS、钓鱼、cookie窃取等漏洞。

有一个留言板,模板代码可能如下:

复制代码 代码如下:


<div>
{{{message}}}
</div>

因为message是用户的输入数据,其留言板的内容,包含了富文本信息,所以这里在xtemplate中,使用了三个大括号,默认不进行HTML转义;那么用户输入的数据假如如下:

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgsjfj.html