谈谈Silverlight的一个跨域安全考虑
在文档中看到Silverlight在设计的时候对网络安全方面做了很多考虑。但由于本人对安全方面并不是特别懂,所以看得挺模糊的。最近和同事黄讨论了其中一些点,得到一些结论,和大家分享一下。
在文档中有这么一段话:
There are important security considerations before you allow Silverlight clients to access Web services in a cross-domain situation. Whenever you put a cross-domain policy file in place you should configure your Web server hosting the Web services to disable browser caching. This enables you to easily update the file or restrict access to your Web services if necessary. Once the cross-domain policy file is checked, it remains in effect for the browser session so the impact of non-caching to the end-user is minimal.
In addition, all Silverlight requests are sent with cookies and authentication. This means that if you have Web services that allow users to access private information, you should host these in a different domain than the Web services exposed to third-party callers. For example, you have a Web store hosted at http://www.tailspintoys.com. Your site allows customers to store billing information that includes credit card numbers. You should not expose a Web service that returns product inventory to third-party Silverlight clients at the same domain. Because cookies and authentication are sent with each message, if you host these Web services on the same domain, you have effectively given the third-party callers access to your customer's private billing information. In this example, your publicly exposed Web services could safely be hosted at http://services.tailspintoys.com, because this is a different domain. You must carefully consider who you have exposed Web services to, and what other Web services are located at that domain. Also, you should always keep your cross-domain policy file as restrictive as possible. For more information about exposing secure Web services, see Security Considerations for Service Access and Making a Service Available Across Domain Boundaries.
我对第二段做了个简单的翻译:
所有的sl请求都会将Cookie和身份验证信息连同发送。这就意味着如果你有一个Web服务,允许用户访问隐私信息,那么你应该将这个web服务放置在其他的域下,和暴露给第三方调用者的web服务的域名区分开。例如,如果你有一个网店放置在http://www.tailspintoys.com,你的网店允许客户存储交易的信息,其中包含了信用卡号码。那么你不应该将一个返回产品清单的web服务放在同个主机域下,然后暴露给第三方的SL客户端。因为Cookie和身份验证信息会和请求连同发送,如果你将这些web服务放置在同个域下的话,你就给了第三方的调用者一个很方便的途径来访问你的客户的私人交易信息。在这个例子中,你暴露给第三方的web服务应该放置在http://services.tailspintoys.com。因为这是一个不同的主机域。你必须非常小心的选择哪些服务可以公开,哪些服务应该部署在那个域下。
我们知道Cookie中有一个主机名的属性,对于只有对于同个主机域的请求,浏览器才会把Cookie连带发送。SL也不例外。
假设这么一种场景:淘宝开放了一个Web服务,这个服务干什么我们并不关心。但是我们知道,如果你想要你的Web服务被其他第三方的客户端调用,你必须在网站下放置一个特定的xml文件,我们称为"安全策略配置"文件,Flash对应的是crossdomain.xml文件,Silverlight除了支持Flash的这个策略文件之外自己也有一套策略配置,放在clientaccesspolicy.xml文件中。与Flash不同的是,SL只会从网站的根目录下去寻找这个策略文件,也就是说即使你的web服务是放在/serivce/目录下的,那么SL客户端也会查找"主机名/clientaccesspolicy.xml"这个文件是否存在(我不清楚为什么要这样设计)。因此淘宝为了让他的Web服务被Silverlight支持,就必须在网站根目录下放置一个策略文件。
假设一个顾客在淘宝www.taobao.com 上面购买了一些东西,登录的会话验证信息可能会存放在Cookie中,然后这个顾客又访问了一个恶意网站(www.eyi.com 当然域名没那么弱了^^),这个恶意网站会向淘宝发送一些登录的HTTP请求。因为这个时候是属于跨域请求,所以Silverlight Runtime会去查找网站根目录下有没有这个策略文件,发现有(并且通过了文件里面定义的访问权限的验证),那么这个请求就会被允许,同时会把你在www.taobao.com 上面的Cookie也连带发送到淘宝系统那里,那么这个时候,这个恶意网站是不是就在你不知情的情况下登录到了淘宝后台,然后这个时候他就可以执行一些你不期望的操作了。
当然这个例子能不能work还有待商榷,只是通过这个例子想告诉大家的是,对于策略安全文件一定要非常小心的配置好访问权限,暴露给第三方的Web服务(涉及到跨域策略安全的),最好放在一个隔离的域下,这样可以降低安全风险。
不知道我这样理解有没有问题,如果不正确的话请纠正我~
下面这张是Silverlight的跨域场景示意图
还要说明的一点是,Silverlight Runtime在检测安全策略文件时,是先检测clientaccesspolicy.xml再检测crossdomain.xml文件(当然拉,自己的东西肯定先检测了)。一旦请求完成,策略文件在整个应用程序会话周期内一直有效(这个感觉和浏览器为了防止DNS Rebinding攻击的做法是类似的),也就是说不用每次都请求这个文件了。如果第一次请求该文件失败,那么接下来的请求同样的也会失败。
策略文件只能放置在根目录下,无论你当前请求的资源是位于网站的哪个目录下。
策略文件本身不允许服务器将其重定向,响应的状态码只能是200或者404,但是请求的资源本身是可以被重定向的,只要源URL和目标URL都在跨域策略文件中声明了。