通常,我们使用HTML来创建交互网站,我们不能保证网络上每一个用户都是正直,友好的,为了大部分友好用户的体验和安全,我们需要关注网站的脆弱性,防止攻击者通过这些弱点进行攻击,窃取用户信息。本篇关注应用程序的安全性及应用程序开发过程中易犯的错误,主要介绍跨站脚本(XSS)和跨站请求伪造(CSRF)。
网络上大部分安全问题都是源于“origin”(源或域)这一概念,主要的攻击都涉及到跨域行为。
XSS,跨域脚本攻击,是当前比较常见的一种网络攻击。
在接受不确定输入内容(如第三方站点消息,URL参数,用户创建的文本批注等)时,在使用前对数据进行验证并且在展示时进行适当的编码是必不可少的,否则,可能会有恶意用户对网站进行攻击,轻者只是传递不规范的数据,严重的可能攻击服务器,扰乱网站正常运行,如,注入SQL脚本清除服务器上所有数据等。
通常编写过滤器验证用户输入时,过滤器应该是基于白名单(已知的安全结构)配置编写,允许白名单通过,不允许其他输入;而基于黑名单(已知的不安全结构)配置编写,即允许除了黑名单之外的所有输入,是不安全的,因为还有许多未知的不安全事物。
通常我们根绝URL中的指定参数,返回给用户不同页面,提供给用户如下导航:
<ul> <li><a href="blog.jhss.com?id=Home">Home</a> <li><a href="blog.jhss.com??id=About">About Site</a> <li><a href="blog.jhss.com??id=Account">My Account</a> </ul>
如上,若以上URL没有编码直接展示给用户,恶意攻击者可以截断URL并插入一个script元素:
http://blog.jhss.com/?id=%3Cscript%3Ealert%28%27Oh%20no%21%27%29%3C/script%3E
若其他用户访问这个URL页面,则会执行注入的script标签内的任意脚本,恶意者可以指定恶意代码,窃取用户信息。
还有很多方式被用来欺骗站点执行注入的代码,如下是我们应该考虑的方面:
<img>
元素,如果允许使用onload属性,则攻击者可以使用onload属性添加回调函数执行任意指定代码。 <base>
元素时,意味着当前页面所有 <script>
元素指向的相对地址都会被 <base>
指定的值拦截,并且页面中所有的表单提交都会被重定向到恶意站点。 CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
若站点允许用户提交表单,如申请修改密码,进行购物结算等,就必须确定该次请求是用户主动发起,而不是别的站点诱骗用户进行请求的,这个问题是因为HTML中表单是允许跨域提交的。
站点为了防止这类攻击,主要可以从两方面进行:
提供用户界面给用户操作,支持用户进行交互的页面,有时候恶意者会诱骗用户激活某些动作,然后对点击的链接进行劫持,引导到恶意网站,进行某些危险交互,这也是我们需要关注的。
常见的一种发生点击劫持的情况是:某个恶意站点将受信站点放置在一个“`
<
iframe> 元素内,然后诱骗用户点击,比如,以红包或者游戏的方式诱骗用户点击,一旦用户开始点击后,恶意站点迅速将
<
iframe>“`元素移动到鼠标指针下,然后欺骗用户点击受信站点的用户界面,然后可以截取到交互数据。
要避免这些情况,对于一些不需要展示在frame窗口内的站点,只允许不在frame窗口时才展示用户界面,如通过检测window对象及其top属性值,更多相关可以查看 framekiller与frame沙盒 。