前端安全的话题再次被提及,大到深航东航系统被攻破,乘客信息泄露并被利用,小到一个word-wrap让服务器暴露信息,各种漏洞和攻击无所不在。在前端江湖中,攻击与防守更像是一场漫无硝烟的战争,悄无声息却无时无刻都在进行。
前端常见漏洞包括XSS、CSRF及界面操作劫持,服务端如SQL注入等。
前端使用的传输协议是http,不经过加密直接传输的。HTML中有很多地方可以内嵌脚本。及前端的存储,cookie,web storage.这些在一定程度上带来了一些安全风险。
同域:两个站点同协议,同域名,同端口。
出于防范跨站脚本攻击的同源安全策略,浏览器禁止客户端脚本(如Javascript)对不同域名的服务进行跨域调用。
同源策略(Same Origin)中的源有着严格的定义,参见RFC6454,第4章节。一般而言,Origin由{protocol, host, port}三部分组成。
下面是同源检查的一些实例
可能有点意外的是,一般我们会认为不同的子域名应该被当做同域名,是安全的调用,但实际上浏览器同源策略甚至禁止了不同子域名和端口的服务之间的调用。
跨子域的访问,可使用iframe,然后设置domain为相同。
HTTP相关头
User-Agent:在使用HTTP协议进行请求时,HTTP协议头部会添加User-Agent,该信息可以标识请求者的一些信息,如什么浏览器类型和版本、操作系统,使用语言等信息。
Referer:HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。比如从我主页上链接到一个朋友那里,他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。HTTP Referer使用非常简单,使用场合比较多的是用于页面统计、资源防盗链等,但还是有一点值得注意的是:Referer是不安全的,客户端可以通过设置改变 Request中的值,尽量不要用来进行安全验证等方面。
HTML中内嵌脚本执行
可内嵌于js文件中,可出现在HTML的script标签中,HTML标签的事件中,及一些标签的src,href等属性的伪协议javascript:中。这样导致防御XSS有些棘手。使用HTTPOnly cookie可以一定程度防止脚本获取cookie。
AJAX
AJAX的请求头设置是有限制的。AJAX严格遵守同源策略。
XSS攻击
XSS是一种经常出现在web应用中的安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin policy)。首先,攻击者向web页面注入恶意代码,然后,这段代码被浏览器执行,这样,一次攻击就成功了。
分类
1.XSS反射型攻击,恶意代码并没有保存在目标网站,通过引诱用户点击一个链接到目标网站的恶意链接来实施攻击的。
2.XSS存储型攻击,恶意代码被保存到目标网站的服务器中,这种攻击具有较强的稳定性和持久性,比较常见场景是在博客,论坛等社交网站上,但OA系统,和CRM系统上也能看到它身影,比如:某CRM系统的客户投诉功能上存在XSS存储型漏洞,黑客提交了恶意攻击代码,当系统管理员查看投诉信息时恶意代码执行,窃取了客户的资料,然而管理员毫不知情,这就是典型的XSS存储型攻击。
一个简单的例子,在发帖子的时候,嵌入
<script>alert('XSS')script>
如果在帖子内容里出现了这样的语句,被浏览器执行了,一次XSS攻击就成功了。 要避免此类攻击,一般会对用户输入采取过滤,最常见的就是对<>转换成<以及>,经过转换以后<>虽然可在正确显示在页面上,但是已经不能构成代码语句了。这个貌似很彻底,因为一旦<>被转换掉,什么就会转换成“<script src=1.js></script>”,不能执行,因此,很多人认为只要用户的输入没有构成<>,就不能闭合前后的标签,其语句当然也不会有害,但是,万事总有可能,只要有一定的条件,我们就可以构造经过编码后的语句来进行XSS。
再比如
<img src='javascript:alert("XSS")'>
这类攻击需要过滤用户输入的src属性,过滤掉里边的javascript开头的关键字,封堵XSS。另外对于各种可能绕过过滤的情况,封堵XSS漏洞。
很多时候,产生XSS的地方会有变量的长度限制,这个限制可能是服务器端逻辑造成的。假设下面代码存在一个XSS漏洞:
服务器端对输出变量$var做了严格的长度限制,那么攻击者可能会这样构造XSS:
希望达到的输出效果是:
" />
假设长度限制为20个字节,则这段XSS会被切割为:
$var输出为: ">
最终的效果是:
" />
中间的代码前部被注释掉了。
XSS的防御:
1)HttpOnly:浏览器将禁止页面的Javascript访问带有HttpOnly属性的Cookie。是为了解决劫持Cookie攻击。因为Javascript获取不到Cookie的值。
C#中设置HttpOnly的方法:
HttpCookie
myCookie=new HttpCookie("myCookie");
myCookie.HttpOnly=true;
Response.AppendCookie(myCookie);
2)输入检查:
常见的Web漏洞如XSS、SQL诸如等,都要求攻击者构造一些特殊字符,这些特殊字符可能是正常用户不会用到的,所以输入检查就有存在的必要了。
例如,用户名可能会被要求只能为字母、数字的组合。
输入检查的逻辑应该放在服务器端,否则很容易被绕过。目前的普遍做法是在客户端和服务器端都执行检查。
在XSS的防御上,输入检查一般是检查用户输入的数据中是否包含一些特殊字符,如< > ' "等。如果发现,则将这些字符过滤掉或编码。
比较智能的还会检查