首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

深入理解Flash的沙箱 – Security Domains_下

2012-10-28 
深入理解Flash的沙箱 – Security Domains_上今天终于有时间把senocular上关于安全域和应用程序域的教程好

深入理解Flash的沙箱 – Security Domains_上

今天终于有时间把senocular上关于安全域和应用程序域的教程好好看了一遍。觉得人家老外就是专业:内容非常有条理且完整,图文并茂,举例也非常实用,真是教程中的精品。刚好我最近也在整理这方面的知识,于是决定把这篇翻译出来,方便国内的读者。对想要进阶理解Flash的运行机制的朋友,本文是不可多得的好材料。

原文地址:http://www.senocular.com/flash/tutorials/contentdomains/

简介

如果你还没有与复杂的的安全域(security domain)和应用程序域(application domain)问题打过交道,那么你真是个幸运的家伙。当你在加载外部内容(然后他们开始播放)的时候,默认的设置工作的很好,你甚至不知道他们的存在。
但是某些时候你可能需要控制默认设置以外的更多行为和功能,这样你就会遇到前面所说的问题。你也许会困扰于Security.allowDomain和crossdomain.xml文件的区别,又或者你想要深究关于安全性的最佳实践。如果是这样,那么这篇文章就是你所需要的了。
以下的教程将会讨论什么是安全域和应用程序域,以及他们在Flash Player中应该如何使用。

安全域
  • Introduction 简介
  • Sandboxing 沙箱
  • Security Domains 安全域
  • Trust 信任授权
  • Non-executable Trust 不可执行文件的信任机制
  • Non-executable Content Without Trust 非受信的不可执行文件
  • SWF Communication Without Trust 在非受信的SWF之间通讯
  • Merging Security Domains 合并安全域
  • Stage Owner and Access 场景的拥有者和获取权限
  • Local Security Domains 本地安全域
    Sandboxing 沙箱

    沙箱是用于区分不同的数据和程序执行。沙箱对于安全性尤其重要。如果没有恰当的信任授权,两个位于不同沙箱内的内容应该没有任何交互。Flash Player的安全模型使用称为安全域的沙箱来分离内容。
    虽然安全性是沙箱的主要用途,但这并不是唯一使用沙箱的原因。另外一种可能的情形是使用沙箱来避免命名冲突,这种区分代码的沙箱方式在Flash Player中被称为应用域

    Security Domains 安全域

    安全域在Flash中是顶级的沙箱。安全域链接到内容的来源域名,或者是被加载的内容(如SWF文件)的来源域名。比如在senocular.com下的SWF文件包含一个链接到senocular.com的安全域,而在example.com下的SWF文件则有一个链接到example.com的安全域。不同的安全域使得SWF文件在Flash Player中播放时运行在自身的沙箱下。

    深入理解Flash的沙箱 – Security Domains_下
    Flash Player中的安全域沙箱

    注意:在本教程的例子中,你将看到我用统一顶级域名下的不同子域来代表不同域名,这是因为在Flash中,不同子域和不同顶级域一样,都被视为不同的域。示例中代码也被简化过了,在Flash编辑环境下用时间线代码也可以进行测试。

    不可执行的内容(非SWF文件),比如图片或者文本文件,也被划分到安全域中,同样与他们所处的域名相关联。实际上,正是域名决定了这些内容是否能够被某个SWF文件加载。更多这方面的内容将在不可执行文件的信任机制章节中进行讨论。

    回到SWF上来,安全域划分了数据和可执行代码。如果两个SWF处于不同的安全域下,某个SWF中的数据(比如某个变量)是不可以被其他SWF获取的,当然,代码也不能执行。如果尝试获取其他域中SWF文件的数据将会产生一个安全错误。

    下面的代码展示了一个SWF文件企图加载另外一个SWF,并获取其文档类的实例(也就是主时间线)。

    http://same.example.com/parent.swf:


    建立信任关系的安全域

    在下面的例子中,一个子SWF文件调用allowDomain来允许父SWF的访问:

    http://home.example.com/parent.swf:

    需要跨域策略文件来加载仅包含数据的文件

    如果文件除了数据以外还有其余用途(图像文件,声音文件等),那么文件还是能够被加载到用户可见(可听)的环境中。比如说图像文件,就算没有跨域策略文件,还是可以在Loader对象中显示给用户看。但是类似BitmapData.draw等直接访问图像数据的方法就不能运行。

    深入理解Flash的沙箱 – Security Domains_下

    需要跨域策略文件来获取其他文件的数据的引用

    对此可能大家都有点疑惑。实际上用户是可以访问这些数据的,但是SWF文件不行。Flash Player是在保护用户的数据不被潜藏有危险代码的SWF文件获取。用户不需要关心跨域策略文件也能正常的浏览网页内容。

    但这并不是说跨域策略文件可以被忽视,类似于下面这种过分纵容的跨域策略文件有很多潜在的危险:

    <?xml version="1.0"?><cross-domain-policy><!-- 小心哦! --><allow-access-from domain="*"/></cross-domain-policy>

    警告:使用通配符(*)允许所有域的访问等同于:用户可能可以接触到的所有处于该域下的数据都有可能被任意SWF文件获取

    客户端的Flash Player运行在当前用户的认证下,这就表示用户的数据可能就是Flash Player的数据。而且Flash Player的数据可能被任意在里面运行的SWF获取。Flash Player默认只允许相同域名下的SWF的安全数据,并限制跨域SWF的运行。如果没有这层限制,SWF可以获取任意当前用户可以获取的数据。

    举个例子:某用户使用他的认证来登录网页的邮件客户端收取邮件,然后用户打开了一个包含有恶意程序的SWF的页面。如果没有跨域限制的话,这个SWF可以用他现有的认证偷偷地加载用户的邮件页面。用户可以访问的内网也不例外,只要用户能去的地方,SWF就能去。幸好Flash Player阻止了这种获取数据的行为,除非该域通过跨域策略文件给予SWF授权。

    记住一个原则,永远不要对包含敏感数据的域开发跨域授权,即使需要上面的信息来进行用户认证。把SWF可以访问的数据划分到不同的域或者子域下面。

    DomainDescriptionPolicy filelogin.example.comHosts user dataNonefeed.example.comHosts public dataIncludes:<allow-access-from domain="*" />

    这将使得敏感数据不可被访问,但是仍然可以对其他域下的SWF文件公开你的其他数据。

    Non-executable Content Without Trust 非受信的不可执行文件

    如果没有跨域策略文件的信任授权,Flash Player禁止非SWF文件的获取。特别是像文本那样的仅包含数据的文件,甚至不会加载。如果你需要从一个没有跨域授权的域中获取数据,还是有一个变通的办法。

    跨域策略文件用于保护数据,特别是保护用户数据,或者说是用户能够接触到的数据。因为Flash Player是运行在客户端的,但是服务器端的代码没有这种限制。服务器完全是另外一台机器,所以用户请求和服务器请求是完全无关的。

    由于服务器没有用户的限制,服务器端的代码可以从任意公开的网络服务获取数据。也就是说包含SWF的服务器可以用于访问外部域的数据,然后作为相同域的数据返回给Flash Player。由于处在相同的域下,Flash Player就不需要有跨域策略文件了。

    下面的代码演示了一个服务器端的php脚本加载外部数据的例子:

    http://home.example.com/loader.swf:

    var urlLoader:URLLoader = new URLLoader();?var urlVariables:URLVariables = new URLVariables();// 服务器端获取外部数据的地址urlVariables.externalURL = "http://away.example.com/content.txt";?// 服务器端的脚本获取外部数据并传给SWFvar serverPage:String = "http://home.example.com/read.php";?var request:URLRequest = new URLRequest(serverPage);request.data = urlVariables;urlLoader.load(request);

    这种解决方案也有一定的问题。首先你必须能够在服务器端部署代码,某些小项目也许根本不需要服务器环境。

    另一个可能更重要的原因是这种方式加倍了网络流量。首先必须从外部域加载到你自己的域下,然后才被下载到你的SWF客户端。同时这也加重了你的服务器的负载。使用跨域策略文件的话就不会有这种问题。

    这可以作为一种解决方案,但最好还是能用跨域策略文件来解决。

热点排行