FLASH沙箱

FLASH沙箱

 

默认情况下,Flash Player(和 AIR 应用程序沙箱以外的 AIR 内容)首先在服务器的根目录中查找名为 crossdomain.xml 的 URL 策略文件,然后在端口 843 上查找套接字策略文件。这些位置上的文件称为“主策略文件”。(对于套接字连接,Flash Player 还会在与主连接相同的端口上查找套接字策略文件。但是,在该端口上找到的策略文件并不视为主策略文件。)

除指定访问权限外,主策略文件还包含一条“元策略”语句。元策略指定哪些位置可包含策略文件。URL 策略文件的默认元策略为“master-only”,它表示 /crossdomain.xml 是服务器上唯一允许的策略文件。套接字策略文件的默认元策略为“all”,它表示主机上的任何套接字都能提供套接字策略文件。

注: 在 Flash Player 9 及更低版本中,URL 策略文件的默认元策略为“all”,它表示任何目录都可以包含策略文件。如果部署的应用程序不是从默认的 /crossdomain.xml 文件而是从其它位置加载策略文件,并且这些应用程序目前可能运行于 Flash Player 10 中,请您(或服务器管理员)务必修改主策略文件以允许其它策略文件。有关如何指定不同元策略的信息,请参阅 Flash Player 开发人员中心主题“Flash Player 9 中策略文件的更改”,网址为www.adobe.com/go/devnet_security_en。

SWF 文件可以通过调用 Security.loadPolicyFile() 方法检索其它策略文件名或其它目录位置。但是,如果主策略文件未指定目标位置能提供策略文件,则调用 loadPolicyFile() 无效,即使该位置有策略文件。在尝试需要策略文件的任何网络操作之前,请先调用 loadPolicyFile()。Flash Player 自动将网络请求加入队列并排在对应的策略文件尝试之后。例如,可以在调用 Security.loadPolicyFile() 之后立即进行网络操作。

在检索主策略文件时,Flash Player 会用三秒钟等待服务器响应。如果未接收到响应,Flash Player 则假定主策略文件不存在。但是,对 loadPolicyFile() 的调用没有默认超时值;Flash Player 假定调用的文件存在,在加载文件之前会一直等待。因此,如果要确保加载主策略文件,请使用 loadPolicyFile() 来显式调用主策略文件。

尽管该方法的名称是 Security.loadPolicyFile(),如果不发出需要策略文件的网络调用,也不能加载策略文件。对 loadPolicyFile() 的调用只是告知 Flash Player 到何处查找所需的策略文件。

系统不会通知您何时启动或完成策略文件请求,也没有必要这样做。Flash Player 执行异步策略检查,自动等待连接的启动直到策略文件检索成功完成。

下面几节介绍只适用于 URL 策略文件的相关信息。有关套接字策略文件的详细信息,请参阅连接到套接字。


URL 策略文件范围

URL 策略文件仅适用于从其中加载该文件的目录及其子目录。根目录中的策略文件适用于整个服务器;而从任意子目录加载的策略文件仅适用于该目录及其子目录。

策略文件仅影响对其所在特定服务器的访问。例如,位于 https://www.adobe.com:8080/crossdomain.xml 的策略文件仅适用于在端口 8080 通过 HTTPS 对 www.adobe.com 进行的数据加载调用。


在 URL 策略文件中指定访问权限

策略文件包含单个 标签,该标签又包含零个或多个 标签。每个 标签包含一个属性 domain,该属性指定一个确切的 IP 地址、一个确切的域或一个通配符域(任何域)。可采用下列两种方式之一来表示通配符域:


单个星号 (*),表示匹配所有域和所有 IP 地址


后接后缀的星号,表示只匹配那些以指定后缀结尾的域


后缀必须以点开头。但是,带有后缀的通配符域可以匹配那些只包含后缀但不包含前导点的域。例如,xyz.com 会被看作是 *.xyz.com 的一部分。IP 域规范中不允许使用通配符。

下面的示例显示了一个 URL 策略文件,该文件允许访问源自 *.example.com、www.friendOfExample.com 和 192.0.34.166 的 SWF 文件。

                           

如果您指定了一个 IP 地址,则将只向使用 IP 语法从该 IP 地址(例如 http://65.57.83.12/flashmovie.swf)加载的 SWF 文件授予访问权限,而不向使用域名语法的 SWF 文件授予访问权限。Flash Player 不执行 DNS 解析。

您可以允许访问来自任何域的文档,如下面的示例所示:

            

每个 标签还具有可选的 secure 属性,其默认值为 true。如果您的策略文件在 HTTPS 服务器上,并且要允许非 HTTPS 服务器上的 SWF 文件从 HTTPS 服务器加载数据,则可以将此属性设置为 false。

将 secure 属性设置为 false 可能会危及 HTTPS 提供的安全性。特别是将此属性设置为 false 时,会使安全内容受到电子欺骗和窃听攻击。Adobe 强烈建议不要将 secure 属性设置为 false。

如果要加载的数据在 HTTPS 服务器上,但是加载数据的 SWF 文件在 HTTP 服务器上,Adobe 建议将加载数据的 SWF 文件移至 HTTPS 服务器。这样,可以使安全数据的所有副本得到 HTTPS 的保护。但是,如果决定必须将要执行加载的 SWF 文件保存在 HTTP 服务器上,则需将 secure="false" 属性添加到 标签,如以下代码所示:

另一种可用于允许访问权限的元素是 allow-http-request-headers-from 标签。此元素授权客户端(此客户端承载其它权限域的内容)向您的域发送用户定义的标头。 标签授权其它域提取您域中的数据,而 allow-http-request-headers-from 标签授权其它域将数据以标头的形式发送到您的域中。在下面的示例中,任何域都可以向当前域发送 SOAPAction 标头:

          

如果 allow-http-request-headers-from 语句存在于主策略文件中,它将应用于主机上的所有目录。否则,它只应用于包含此语句的策略文件所在的目录和子目录。


预加载策略文件

从服务器加载数据或连接到套接字是一种异步操作。Flash Player 只是等待策略文件完成下载,然后才开始主操作。但是,从图像中提取像素数据或从声音中提取采样数据是一种同步操作。必须先加载策略文件才能提取数据。加载媒体时,请指定媒体检索策略文件:


使用 Loader.load() 方法时,设置 context 参数的 checkPolicyFile 属性,该参数是一个 LoaderContext 对象。


使用 标签在文本字段中嵌入图像时,将 标签的 checkPolicyFile 属性设置为 "true",如下所示:


使用 Sound.load() 方法时,设置 context 参数的 checkPolicyFile 属性,该参数是一个 SoundLoaderContext 对象。


使用 NetStream 类时,设置 NetStream 对象的 checkPolicyFile 属性。


设置上述参数时,Flash Player 首先会检查是否已经为该域下载了任何策略文件。然后,它查找服务器上默认位置中的策略文件,同时检查 语句和是否存在元策略。最后,考虑对 Security.loadPolicyFile() 方法的所有未处理的调用,以查看它们是否在范围内。

---------------------------------------------------------------------------

Flash Socket安全问题的全面解析(转)(2009-02-19 11:28:30)

标签:杂谈
分类:as

以下原文转帖自我的博客:www.iflashigame.com(http://hi.baidu.com/mr_ziqiang)
昨天做测试的时候遇到一个问题,做好的SWF在Flash AS3中调试通过,但是发布到html中之后就无法得到数据了。查了一些资料之后找到了解决办法。这里感谢 剑心提供帮助,以及同事若水三千提供Java代码及日志记录。
1、问题描述
将flash发布为html格式后,加载页面后,swf无法与服务器进行socket通信。Flash端显示的错误为:
securityErrorHandler信息: [SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048"]
在服务器端显示的信息是由客户端尝试进行连接,但是无法接受数据。接受的数据显示为空。
2.问题原因:
最新的Flash player 9.0.124.0,当flash文件要进行socket通信的时候,需要向服务器端获取crossdomain.xml文件。如果找不到就出现客户端无法连接服务器的现象。
了解flash发起socket通信的三个过程
当封装在页面的flash发起socket通信请求的时候会先寻找服务器端的843端口,获取Crossdomain.xml文件,当服务器没有开启843的时候,flashPlayer会检查发起请求的swf文件中中有没有使用Security.loadPolicyFile来加载策略文件Crossdomain.xml,如果还是没有就会看这个发起请求的swf要连接的目标端口有没有策略文件。如果都没有那么连接失败,返回如上的出错提示。
为什么老版本的Flash player没有这个问题?
从一些官方的一些资料中了解了一下。以前的Flash Player无论你采用urlRequest的http请求方式或者xmlsocket socket方式,他们都共用一个安全策略文件。这个策略文件只要你放在主域的目录下就行了。而现在不行了,现在的策略文件如果你使用http请求方式那么需要把策略文件放在目录下面,如果你使用socket请求方式就必须通过socket端口来接收这个策略文件。
对应调用的方式为:
http请求——》Security.loadPolicyFile(“http://www.xxx.com/crossdomain.xml”)
socket或xmlsocket请求——》Security.loadPolicyFile(“xmlsocket://www.xxx.com:port”)
怎么将Socke策略文件发给Flash Player
Flash Player在你的socket.connect("domain",port)运行之前,会按照前面描述的三个过程向你的socket服务器的843端口(据说Adobe已经向相关管理机构申请保留843端口给Flash Player用)发送一个字符串 "",这个时候如果你有一个服务在监听843端口那么收到这个字符串之后,直接按照XML格式发回策略文件就解决了。(注意发回的时候记得加一个截止字符"\0")
当然你也可以不用843端口自己设置一个端口。因为Flash Player如果在843端口得不到信息,就会检查你是否在你的Flash文件里面自己添加了指定的获取通道,你可以定义一个自己的端口。不过这个时候你不能用http方式,而要用xmlsocket方式。(相当于自动帮你新建了一个xmlsocket对象,然后链接你指定的主机和端口)。比如你想用1234端口可以在你的Flash里面加这一句Security.loadPolicyFile(“xmlsocket://www.xxx.com:1234”),需要注意的是这一句要加在你的socket.connect前面。
还有最后一个办法,就是在你的socket连接端口监听这个请求。比如你用的是socket.connect("192.168.1.100",8888),那么在你的服务器加一段接收字符串""的代码,当接到这个字符串时将策略文家按照xml格式发到客户端。
关于策略文件的格式(可以在Flash CS3帮助里面的Flash Player安全性——》控制权限概述中找到)
1、针对web应用的策略文件
下面的示例显示了一个策略文件,该文件允许访问源自 *.iflashigame.com 和 192.0.34.166 的 SWF 文件。





注意事项:
默认情况下,策略文件必须命名为 crossdomain.xml,并且必须位于服务器的根目录中。但是,SWF 文件可以通过调用 Security.loadPolicyFile() 方法检查是否为其它名称或位于其它目录中。跨域策略文件仅适用于从其中加载该文件的目录及其子目录。因此,根目录中的策略文件适用于整个服务器,但是从任意子目录加载的策略文件仅适用于该目录及其子目录。
策略文件仅影响对其所在特定服务器的访问。例如,位于 https://www.adobe.com:8080/crossdomain.xml 的策略文件只适用于在端口 8080 通过 HTTPS 对 www.adobe.com 进行的数据加载调用。
2、针对Socket的策略文件







这个策略文件是指定允许哪些域的主机通过那些端口链接。
参考文章
flash xmlsocket policy 问题
Policy file changes in Flash Player 9
Setting up a socket policy file server
Understanding Flash Player 9 April 2008 Security Update compatibility
获取策略文件的Java服务器端代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SecurityXMLServer implements Runnable {
private ServerSocket server;
private BufferedReader reader;
private BufferedWriter writer;
private String xml;
public SecurityXMLServer()
{
String path = "policyfile文件路径";
//此处的换成相应的读取xml文档的方式如dom或sax
//xml = readFile(path, "UTF-8");
xml=" "
+""
+"
";
System.out.println("policyfile文件路径: " + path);
System.out.println(xml);
//启动843端口
createServerSocket(843);
new Thread(this).start();
}
//启动服务器
private void createServerSocket(int port)
{
try {
server = new ServerSocket(port);
System.out.println("服务监听端口:" + port);
} catch (IOException e) {
System.exit(1);
}
}
//启动服务器线程
public void run()
{
while (true) {
Socket client = null;
try {
//接收客户端的连接
client = server.accept();
InputStreamReader input = new InputStreamReader(client.getInputStream(), "UTF-8");
reader = new BufferedReader(input);
OutputStreamWriter output = new OutputStreamWriter(client.getOutputStream(), "UTF-8");
writer = new BufferedWriter(output);
//读取客户端发送的数据
StringBuilder data = new StringBuilder();
int c = 0;
while ((c = reader.read()) != -1)
{
if (c != '\0')
data.append((char) c);
else
break;
}
String info = data.toString();
System.out.println("输入的请求: " + info);
//接收到客户端的请求之后,将策略文件发送出去
if(info.indexOf("") >=0)
{
writer.write(xml + "\0");
writer.flush();
System.out.println("将安全策略文件发送至: " + client.getInetAddress());
}
else
{
writer.write("请求无法识别\0");
writer.flush();
System.out.println("请求无法识别: "+client.getInetAddress());
}
client.close();
} catch (Exception e) {
e.printStackTrace();
try {
//发现异常关闭连接
if (client != null) {
client.close();
client = null;
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
//调用垃圾收集方法
System.gc();
}
}
}
}
//测试主函数
public static void main(String[] args)
{
new SecurityXMLServer();
}
}

你可能感兴趣的:(FLASH沙箱)