zoukankan      html  css  js  c++  java
  • [转]Web客户端安全性最佳实践(转)

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

    HTTP?想都别想

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

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

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

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

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

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

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

    Secure和HttpOnly属性

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

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

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

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

    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) {
       ...
    }
    
    
    

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

    正确的做法是使用跨域资源共享。它允许资源提供方在响应头中加入一个特殊的标记,使你能通过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上实现越来越丰富的功能。但是我们也不能掉以轻心,因为网络中攻击和威胁无处不在,在敲第一行代码之前就要好好想一想安全性方面的问题。

  • 相关阅读:
    phpcms后台进入地址(包含No permission resources错误)
    phpmyadmin上传大sql文件办法
    ubuntu彻底卸载mysql
    Hdoj 2602.Bone Collector 题解
    一篇看懂词向量
    Hdoj 1905.Pseudoprime numbers 题解
    The Python Challenge 谜题全解(持续更新)
    Hdoj 2289.Cup 题解
    Hdoj 2899.Strange fuction 题解
    Hdoj 2199.Can you solve this equation? 题解
  • 原文地址:https://www.cnblogs.com/study-development/p/3515703.html
Copyright © 2011-2022 走看看