[ WWDC2018 ] - Web安全策略 Strategies for Securing Web Content

web安全策略

web安全对iOS开发者来说重要吗?重要!APP中通常会使用很多web页面,例如广告、登录流程、闪屏,或者需要使用跨平台功能的时候。你可能在页面中仅仅一部分使用web,也可以整个页面都是webView,甚至做一个web app。因此web安全对于app来说非常重要。

来自web的安全攻击有以下几种:

  • 跨域攻击
  • 预测执行攻击
  • 窗口控制攻击

本文将针对这三种攻击类型,给出安全防御措施。

安全传输

网络传输相信大家都很熟悉了,安全的传输能够保证接收到的数据来自可信任的站点,并且在传输工程中不会被篡改。安全传输是其它安全措施的基础,采取的措施包括:

  • HTTPS和WSS(webSocket Secure)
  • Http Strict Transport Security(HSTS)遵循HTTPS安全协议的web只能访问同样遵循HTTPS安全协议的内容,不能访问遵循HTTP不安全协议的内容。
  • Upgrade-Insecure-Requests 请求头中添加这一项表示web支持更加安全的升级机制,服务器可以重定向到这个站点的安全版本。
  • 使用cookie确保安全,cookie只能被安全的传输,例如千万不要把cookie放到粘贴板上
  • 在app的info.plist文件中 Xnip2018-06-162_20-24-05.jpg

Allow Arbitrary Loads in Web Content 这个开关一定要置为 NO!

跨域封锁

web的内容可以来自任何站点,例如,webView上的一张图片可以来自任何服务器,也可以从任意服务器上加载一个脚本或iframe。需要注意的是要当心来自其它服务器的资源。跨域的保护已经有20多年的历史,并且形成了基本原则--同源策略:只有和页面来源相同的脚本才会被该页面执行。例如iframe来自不同的域名,同源策略不允许加载这个iframe。仅仅靠同源策略还是不够的,还需要采取其它的防御措施。

1. Subresource Integrity

服务器可能会发生异常导致下发错误的资源使得web发生crash,但是开发者通常是知道所要请求哪个资源的,在脚本里面增加一个检查签名。如果签名匹配则认为是下发了正确的资源,如果不匹配仍然可以正常工作,此时尝试从页面的资源里查找或者从自己的服务器重新加载。这样做虽然降低了性能,但是提升了安全性。

<script src="https://cdn.example/framework.js"  
 integrity="sha256-8WqyJLuWKRB...oZkCnxQbWwJVw=">
</script>

window.framwork || // reload from own domain  

2. Content Security Policy

HTTP response:  
:status:200
Content-Security-Policy:  
    default 'self';  // No inline
    script-src cdn.example;
    frame-src social.example;
    frame-ancestors news.example;

HTTP response的Header里面,default设置成自己,默认只能加载同源的资源;script-src和frame-src 分别指定可信任的脚本和iframe的来源;frame-ancestor设置成news.example,指定只有news.example可以iframe我们的web。

另外不使用inline属性的脚本也是一种防御措施,不使用inline脚本,只从文件加载脚本,这么做分离了逻辑和文件,更加安全。

3. HttpOnly cookies

HTTPOnly cookies作为一种安全措施,已经有至少15年的使用历史。在这之前script通过document.cookie这个强大的api能拿到文档的cookie,留下安全隐患。HTTPOnly cookies能够阻止这种情况,只允许HTTP请求访问cookie,禁止使用script访问cookie。它的使用方式很简单,只需要在HTTP response的Header里面加上HttpOnly这一项,如下

HTTP response:  
:status:200
Set-Cookie:  
    auth = abc...123; HttpOnly;

4. SameSite cookies

在HTTP response的Header里面将SameSite cookies这一项设置为Strict,那么将不允许把cookie从一个域名发送到另一个域名。例如其他人的web里面嵌入了我们的web,如果我们的服务器HTTP response的Header里面SameSite cookies = Strict,那么其他人将无法使用他的cookie来访问我们的服务器。

HTTP response:  
:status:200
Set-Cookie:  
    auth = abc...123; HttpOnly;
    SameSite=strict

5. Cross-Origin-Resource-Policy

Cross-Origin-Resource-Policy是推出的新功能。之前web可以加载任意web中的资源,例如图片或者script。在HTTP response的Header里面将Cross-Origin-Resource-Policy这一项设置为Same,将不允许别人的web向我们的服务器请求图片或者script,但是我们自己的web可以。

HTTP response:  
:status:200
Cross-Origin-Resource-Policy:Same

6. Cross-Origin-Window-Policy

Cross-Origin-Window-Policy也是新推出的功能。之前通过window.open这个强大的api,其他人的web可以在新窗口中打开我们域名下的web,通过一些手段可以修改我们的web,导航到攻击者指定的页面。在HTTP response的Header里面将Cross-Origin-Resource-Policy这一项设置为Deny,将阻止其他人修改我们web中的内容,当然别人仍然还是可以打开我们的web。Cross-Origin-Resource-Policy适用于希望使用post message 进行窗口间通信,但是不想让别人控制我们自己web内容的情况。

HTTP response:  
:status:200
Cross-Origin-Window-Policy:Deny

常见的web攻击及防御手段

1. Cross-Origin Attacks

  • Cross-Site Scripting
  • Compromised CDN
  • Cross-Site Request Forgeries

1. Cross-Site Scripting

例如我们的web里面有一个文本框,用户可以输入文字,如下图。假如攻击者注入了这么一段脚本,如果没有采取防御措施,那么我们web的cookie就会被盗取。

Xnip2018-06-163_16-05-42.jpg

在HTTP response的Header中添加HTTPOnly这一项,就能阻止脚本访问文档的cookie,从而防御跨域脚本攻击。 另外一种防御手段是Content-Security-Policy,如下

HTTP response:  
:status:200
Content-Security-Policy:  
    default-src 'self';  // No inline

Content-Security-Policy能保证拒绝加载外部来源的脚本,并且不使用inline属性的脚本,只从文件中加载脚本。

2. Compromised CDN

例如我们的web需要从某个外部资源装载一个framework,攻击者可能拦截这个请求,并把它重定向到自己的攻击脚本上,如下图 Xnip2018-06-163_16-22-01.jpg

使用Content-Security-Policy中script-src这个属性可以指定信任的脚本来源,并且在引用资源的时候指定来源和校验签名,如下

在HTTP response中:

HTTP response:  
:status:200
Content-Security-Policy:  
    default-src 'self';  
    script-src cdn.example;

在HTML中:

<script src="https://cdn.example/framework.js"  
 integrity="sha256-8WqyJLuWKRB...oZkCnxQbWwJVw=">
</script>

window.framwork || // reload from own domain  

3. Cross-Site Request Forgeries

攻击者可能在自己的web中嵌入我们的web,然后向我们的服务器发起一个伪造的网络请求(使用的是攻击者网站的cookie),如下图 Xnip2018-06-163_16-33-06.jpg

如果采取了防御措施,将HTTP response的Header里面的SameSite设置为strict,那么就会禁止攻击者网站的cookie发动到我们的服务器上面,如下

HTTP response:  
:status:200
Set-Cookie:  
    auth=abc...123; SameSite=strict

2. Speculative execution attacks (Spectre)

防御措施有:
* WKWebView
* Content Security Policy
* HttpOnly cookies
* SameSite cookies
* Cross-Origin-Resource-Policy

Speculative execution 的定义:预测执行类似于批量执行条件判断语句,例如计算机大量执行"x是否会造成数组array越界"这条指令,就能推测出这个数组的长度,进一步推测出这个数组在内存缓冲区中的地址边界。利用缓冲区溢出这种攻击手段,可以向web中注入攻击脚本。当x超过数组边界的时候,本来应该执行越界的error回调,但是确取出了攻击脚本并执行,造成数据泄露。显然只靠同源策略是无法防御这种攻击的,因为攻击脚本和文档处在同一个域名下,并且在同一个线程中。

Xnip2018-06-164_10-36-53.jpg

防御预测执行攻击的方法是确保web内容和其他iframe(例如攻击脚本)处在不同的线程中

1. WKWebView

Xnip2018-06-164_17-09-22.jpg

以Safari app为例,WKWebView会单独分离出一个NetWork线程用于处理添加cookie等逻辑,而且每个网页处在不同的线程当中,所以evil网页是无法通过预测执行攻击手段攻击我们的页面。而且因为NetWork线程也是独立的,所以evil网页也无法通过预测执行攻击手段拿到重要数据,例如cookie。
如果使用UIWebView,所有的web包括NetWork线程都在app的同一个线程中,所以是无法防御预测执行攻击手段的。

2. Content security policy

Content security policy的封锁功能是处于Network线程中,和web线程是分离的,因此可以防御预测执行攻击手段。
例如web要加载一个广告iframe,但是这个广告iframe被重定向到了一个攻击脚本,如果使用了Content security policy,如下,因为攻击脚本不在信任的frame-src里面,所以会禁止加载。还有一种情况,攻击者的web引入了我们的web,因为设置了frame-ancestors为none,所以会禁止攻击者网站引入我们的web,从而防御攻击。

HTTP response:  
:status:200
Content-Security-Policy:  
    default-src 'self';  
    frame-src ad.example
                social.example
    frame-ancestors 'none'

3. HttpOnly cookies 和 SameSite cookies

HttpOnly cookies 和 SameSite cookies的封锁功能也是处于Network线程中,和web线程是分离的,因此可以防御预测执行攻击手段。HttpOnly cookies能够禁止攻击者通过脚本拿到cookie。SameSite cookies设为strict能够禁止cookie从一个域发送到另一个域。

4. Cross-Origin-Resource-Policy

Cross-Origin-Resource-Policy的封锁功能也是处于Network线程中,和web线程是分离的,因此可以防御预测执行攻击手段。Cross-Origin-Resource-Policy设置成Same能禁止攻击者的web加载我们网站的资源。

3. Window Control Attacks

Cross-Origin-Window-Policy

Xnip2018-06-164_15-17-59.jpg

攻击者的页面可以通过window.open这个api在新的窗口打开我们的web,攻击者趁我们不注意的时候,把我们的页面导航到钓鱼页面,然后诱导用户填写用户名和密码,这样就窃取到了用户信息。把HTTP response Header里面的Cross-Origin-Window-Policy设置为Deny,能够禁止攻击者修改我们的web,这样攻击者就无法导航到钓鱼页面。

总结

每种安全措施防御的攻击类型

Xnip2018-06-164_16-49-07.jpg

建议

  • 使用安全的网络传输(例如https,wss)
  • 设置Cookies为HttpOnly和其它安全选项
  • 把UIWebView升级到WKWebView
  • 测试防御措施是否生效,web是否仍然能正常工作。安全措施都具有一定的限制功能,因此测试web是否能正常工作非常重要。例如Content-Securityp-Policy的script-src白名单里少些了一个允许的域名,那么这个域名下的web就无法正常使用了。
本文总阅读量