Web客户端安全性最佳实践

标签: IT技术 互联网 安全 最佳实践 浏览器 | 发表时间:2014-01-10 00:35 | 作者:njuyz
出处:http://blog.jobbole.com

得益于HTML5,Web应用中越来越多的逻辑从服务器端迁移到了客户端。因而,前端开发人员也需要更多关注安全性方面的问题。在这篇文章中,我会告诉你如何使你的应用更加安全。我会着重描述一些你可能从未听说过的技术,而不是仅仅告诉你“别忘了对用户提交的页面数据做转义(escape)”。

HTTP?想都别想

当然,我并不想让你通过FTP或者普通的TCP协议来传输你的数据。我的意思是,如果你想让你的用户安全地访问你的网站,你应该使用SSL(HTTPS)来加密你的数据传输。不仅要加密登陆节点或者关键信息,而是要加密所有的数据。否则当用户通过公用网络访问你的应用时,他看见的内容说不定已经被别人“黑”掉了。这就叫中间人攻击,见下图:

main-in-the-middle
(译者注:此处引用的原图中笔误,中间人攻击的英文为Man-In-The-Middle Attack)

如果你使用SSL,所有的数据在发送之前就会被加密,即使攻击者在网络中截获了数据包,他也没有办法查看或者篡改其中的内容。对于提升应用的安全性,这是目前为止最重要的一步。

严格传输安全性标记(Strict-Transport-Security)

如果你只想通过SSL来传输你的数据,那么这个HTTP头属性会让你觉得非常好用。如果服务器端在响应头中使用了这个标记(你也可以在页面中使用 <meta>标签,不过这样的话就会存在一个未被加密的请求),那么所有从客户端到服务器端的数据都会被加密。使用方式如下:

Strict-Transport-Security: max-age=3600; includeSubDomains

其中的 includeSubDomains属性是可选的,你可以使用它来加密当前域的子域,所有对子域的访问也会被HTTPS加密。而其中的 max-age属性可以设置在多长的时间范围内(以秒为单位)需要用SSL对页面数据传输进行加密。不过可惜的是,目前只有Firefox、Chrome和Opera浏览器支持这个标记。

Secure和HttpOnly属性

还有一种方法可以有效增强HTTP和HTTPS访问的安全性,那就是使用 SecureHttpOnly这两个cookie属性。前者能确保cookie的内容只通过SSL连接进行传输;而后者正好相反。如果你觉得这两者互相矛盾,没啥用处,那就错了。它们告诉浏览器cookie的内容只能分别通过HTTP(S)协议进行访问,从而避免了被别人轻易窃取,比如JavaScript中的document.cookie.

通过Content-Security-Policy(CSP)标记来减少跨站脚本攻击(XSS)的危害

如果你觉得依靠XSS过滤器能够防范所有可能的XSS攻击,不妨先看一看 这篇文章,再好好思考一下。当然,为整个Web应用都配置上完备的防范措施也会存在一些问题,比如,可能拖累整个网站的性能。不过我还有一招。

这招叫做Content-Security-Policy标记。它能让你指定网站上所有脚本和图片等资源的源站点。此外,它还能阻止所有内联(inline)的脚本和样式。即使有人在页面评论或者回帖中嵌入了脚本标签,这些脚本代码也不会被执行。CSP标记一般写在HTTP头中(也可以写在HTML的 <meta>标签中),写法如下:

Content-Security-Policy: policy

其中的policy字段代表一系列CSP属性,下面列举一些常用的属性:

  • script-src – 设置可以接受的JavaScript代码的源站点
  • style-src – 设置可以接受的CSS样式代码的源站点
  • connect-src – 定义浏览器可以通过XHR、WebSocket或者EventSource访问哪些站点
  • font-src – 设置可以接受的字体文件的源站点
  • frame-src – 定义浏览器可以通过iframe访问哪些站点
  • img-src – 设置可以接受的图片的源站点
  • media-src – 设置可以接受的音频和视频文件的源站点
  • object-src – 设置可以接受的Flash和其它插件的源站点

如果没有设置上述属性,那么浏览器默认会接受来自任何源站点的脚本和数据。不过浏览器的默认属性也能通过 default-src属性来设置。其它的属性如果没有设置的话,就会默认采用这个属性中设置的值。此外,还有一个叫做 sandbox的属性,它可以让浏览器以iframe的形式加载页面。下面是一个CSP头的例子:

Content-Security-Policy: default-src: 'self'; script-src: https://apis.google.com;

在这个例子中,浏览器只会加载源自这个Web应用所在站点的资源(默认源设置为self),以及通过Google API服务器获取的脚本。CSP有很多种灵活的用法,如果使用得当,可以有效提升Web应用的安全性。

CSP的缺点

当你使用CSP的时候,有一点千万要记住:默认情况下,所有的内联JavaScript脚本都不会被执行。例如:

内联的事件监听器:比如

<body onload="main();">

所有的javascript URL:比如

<a href="javascript:doTheClick()">

之所以这样,是因为浏览器无法区分你的内联脚本和黑客注入的脚本。你需要通过JavaScript的 addEventListener或者一些框架中类似的函数来重写上述脚本。某种程度上来看,这也不算一件坏事,它逼你不得不分离逻辑层的代码和展现层的代码,而你本来就应该这么做。此外,CSP默认还会阻止所有eval()风格的代码的执行,包括 setInterval/setTimeout中的字符串和类似于 new Function(‘return false’)之类的代码。

CSP的可用性

大部分时下流行的浏览器都支持CSP。Firefox、Chrome和Opera(包括手持设备上的)使用标准的CSP头。Safari(包括iOS中的)和安卓上的Chrome使用 X-WebKit-CSP头。IE10(仅支持sandbox属性)使用 X-Content-Security-Policy头。所以,由于IE的支持(部分支持也是支持),你不仅可以着手使用CSP(除非你用的是Google Chrome Frame之类的东西),而且还能在各种实际的浏览器中运行,有效地改善Web应用的安全性。

使用跨域资源共享(Cross Origin Resource Sharing)来代替JSONP

目前由于浏览器同源策略的限制,JSONP常被用于从其它服务器上获取数据。通常的办法是在脚本中写一个回调函数,然后把回调函数的名字写在请求的URL中,像下面这样:

function parseData(data) {
   ...
}
<script src="http://someserver.com/data?format=jsonp&callback=parseData"></script>

但是这样做会有很大的安全隐患。如果你请求数据的服务器被黑了,那么黑客就能在返回的数据中植入恶意代码,进而窃取用户的隐私信息。因为在浏览器看来,通过这种方法获取的脚本代码和正常的页面代码没什么区别。

正确的做法是使用跨域资源共享。它允许资源提供方在响应头中加入一个特殊的标记,使你能通过XHR来获取、解析并验证数据。这样就能避免恶意代码在你的应用中执行。

这个方法需要在响应头中加入的标记如下:

Access-Control-Allow-Origin: allowed origins

这里可以列举一些可以接受的数据源,以逗号隔开,使用通配符*来接受所有的数据源。

CORS可用性

目前所有主流的浏览器都支持,除了Opera Mini。

当然,更重要的是数据提供方能支持跨域资源共享,不过这就不是开发者能说了算的了。

在iframe中使用sandbox属性

如果你使用iframe加载外部网站的内容,也别忘了它的安全问题。你可以通过iframe的 sandbox属性来增强iframe使用的安全性。通过设置sandbox属性,可以使得iframe无法随意跳转页面,无法执行外部脚本,无法锁定鼠标,无法弹出新窗口,无法提交表单,等等。此外页面上若干个iframe中加载的所有内容还必须来自唯一的源,也就不能使用 localStorage等有悖于同源策略的东西。当然,如果有需要的话,你也可以通过显式的设置来放宽限制,可以设置的属性如下:

  • allow-same-origin –iframe只要各自符合同源规范即可
  • allow-scripts –iframe中可以执行JavaScript脚本
  • allow-forms –iframe中可以提交表单
  • allow-pointer-lock –iframe中可以锁定鼠标
  • allow-popups – iframe中可以弹出新窗口
  • allow-top-navigation – iframe中可以完成页面跳转

可用性

目前iframe的 sandbox属性受各种主流浏览器支持,除了Opera Mini以外。

结束语

主要内容就是这些了。希望读者能通过这篇文章学到一些新技术,能用于今后的项目中,更好的提升Web应用的安全性。得益于HTML5的发展,我们可以在Web上实现越来越丰富的功能。但是我们也不能掉以轻心,因为网络中攻击和威胁无处不在,在敲第一行代码之前就要好好想一想安全性方面的问题。

Web客户端安全性最佳实践,首发于 博客 - 伯乐在线

相关 [web 客户端 安全] 推荐:

Web客户端安全性最佳实践

- - 博客 - 伯乐在线
得益于HTML5,Web应用中越来越多的逻辑从服务器端迁移到了客户端. 因而,前端开发人员也需要更多关注安全性方面的问题. 在这篇文章中,我会告诉你如何使你的应用更加安全. 我会着重描述一些你可能从未听说过的技术,而不是仅仅告诉你“别忘了对用户提交的页面数据做转义(escape)”. 当然,我并不想让你通过FTP或者普通的TCP协议来传输你的数据.

Html5 客户端存储安全

- - Web前端 - ITeye博客
HTML 5 在客户端存储上的内容更丰富,更强大了,比如cookie只能存4k的内容,而HTML5标准里,可以存数十M都没有问题. 在未来可能很多隐私数据都会保存在客户端,这其实也提高了风险. 在html5中的客户端存储有3个. 和cookie类似,在新的html 5中使用的是 Session Storage,不过它的生效时间不再由程序员指定了.

iOS客户端开发与Web前端开发

- - bang's blog
不知不觉做iOS客户端开发已经半年多了,了解到iOS客户端开发与Web前端开发的一些异同,写一下. 用户角度上看,客户端升级必须让用户手动下载整个新的安装包覆盖安装,而web的升级无需用户做任何事情. 开发角度上看,如果客户端有个小bug需要紧急修复,需要修复完后打包一个完成的安装包,给一个版本号,发布给用户升级.

Web项目如何防止客户端重复发送请求

- - SegmentFault 最新的文章
在Web项目中,有一些请求或操作会对数据产生影响(比如新增、删除、更新),针对这类请求一般都需要做一些保护,以防止用户有意或无意的重复发起这样的请求导致的数据错乱. 本文总结了一些防止客户端重复发送请求的方法. 方法一:JS监听Form的onsubmit事件. 在经典场景下,浏览器通过Form发送请求.

安全隐患名录-Web

- - Onlycjeg's Blog
[0day储藏室出品]安全隐患名录-Web. 本文档是基于OWASP TOP 10写成,描述了OWASP TOP 10中所讲到的风险并对其进行风险等级鉴定,漏洞描述,漏洞危害,测试方法,测试过程对系统的影响以及修复方法. 在做项目的过程中,我们所面对的更多的是生产系统,并不是所有的企业都存在测试服务器.

简单几步实现用Web客户端来管理SqlServer2008数据库

- yasy - 博客园-首页原创精华区
上面说的是以前的做法,但自从换到Mac下用虚拟机来开发后对虚拟机的文件使用就比较敏感了,不想再安装超过百M的Sql Server Management Studio Express了,想使用Web版本的管理器了,毕竟Web版本的管理器才几M,也能完成我平常所做的操作. 下面是我安装Web版本的管理器步骤,有类似需求的朋友参考一下吧.

手机安全公司Lookout推出iPhone客户端

- SotongDJ - 36氪
随着智能手机日益普及,丢手机成为一种必然发生的小概率事件. 由于智能手机越来越智能,里面存储的信息越来越多、越重要,如何保证手机的信息安全是一个让人挠头的问题. 如果你的手机丢了,如何确定手机位置呢. 万一你使用的WiFi会记录你的网银密码呢. 和PC平台一样,移动平台上的数据安全也越来越受到人们的重视.

移动客户端与服务器端安全通信方案

- - CSDN博客移动开发推荐文章
    手机移动端与服务器端安全通信一直是个问题,让人比较头疼,最近在网上查了一些资料,总结了一下得出了一个自我感觉还好的方案,分享一下,也希望得到大家的批评斧正.     CS,C客户端,S服务器端.     在客户端软件发布前,客户端保存一个公钥,服务器保存一个私钥.     C1:客户端随机生成一个对称密钥K,使用公钥加密内容(K+账户+密码).

Web开发框架安全杂谈

- goodman - 80sec
最近框架漏洞频发,struts任意代码执行、Django csrf token防御绕过、Cakephp代码执行等等各大语言编程框架都相继暴出高危漏洞,这说明对于编程框架的安全问题已经逐渐走入安全工作者的视线. Web开发框架就相当于web应用程序的操作系统,他决定了一个应用程序的模型结构和编程风格.

[转][转]浅谈php web安全

- - heiyeluren的Blog
来源: http://www.phpben.com/?post=79. 首先,笔记不是web安全的专家,所以这不是web安全方面专家级文章,而是学习笔记、细心总结文章,里面有些是我们phper不易发现或者说不重视的东西. 在大公司肯定有专门的web安全测试员,安全方面不是phper考虑的范围. 但是作为一个phper对于安全知识是:“ 知道有这么一回事,编程时自然有所注意”.