Accessibility

Table of Contents

Creating more secure SWF web applications

Complex cross-domain implementations

The following sections discuss more complex, cross-domain implementations, including cross-domain policy files in sub-directories, utilizing meta-policies, and socket policy files.

Utilizing crossdomain.xml in subdirectories

If you'd like to get more information about how to work with the loadPolicyFile method, see loadPolicyFile() in the ActionScript 3.0 Language and Components Reference.

HTTP policy files can be specified from subdirectories in order to define access for that directory and all of its subdirectories. Therefore, rather than creating a very general crossdomain.xml file in the root directory of a site, an administrator can allow users to define their own crossdomain.xml files within their subdirectories for their specific needs. For instance, a developer who needs to specify domain="*" can specify that permission in a sub-directory crossdomain.xml file to expose only that directory as an alternative to placing domain="*" in the root crossdomain.xml file. This may be useful in situations where a developer creates local-with-networking SWF files which require a domain="*" setting to communicate with a public website. Crossdomain.xml files hosted from a subdirectory can not define access to ports.

The following code example illustrates how to load a policy file from a subdirectory:

//Load a policy file which allows cross-domain access to the ~user1 directory
System.security.loadPolicyFile("http://www.example.com/~user1/myPolicy.xml");
 
//Access data under the ~user1 directory
NetStream.play("http://www.example.com/~user1/vids/myVideo.flv");

Avoid using FlashVars in loadPolicyFile() calls

Related threats: Cross-site request forgery

Developers should avoid obtaining URLs from FlashVars for use in the loadPolicyFile method. If the attacker can control the FlashVar, then they can use the loadPolicyFile method to make a cross-domain GET request and send arbitrary data to a remote site. This could result in an unauthorized information disclosure or a cross-site request forgery attack. If a developer must accept the location as a FlashVar, then the developer should takes steps to make sure that the URL is on an approved whitelist before providing the URL to the loadPolicyFile method.

Meta-policies can be used to control sub-domain crossdomain.xml files

For more information on meta-policies, please see Policy file changes in Flash Player 9 and Flash Player 10: Meta-policies.

Allowing any user on a system to create a crossdomain.xml file for their directory is of frequent concern to many system administrators. In some instances, system administrators want to be the only entity capable of defining cross-domain permissions. Starting with Flash Player 9 Update 3, Flash Player acknowledges controls set by the system administrators to limit which directories are allowed to create crossdomain.xml files. These options that are specified within a <site-control/> directive include:

  • none: No policy files are allowed anywhere on the server, including the master policy file. Any allow-access-from information included after the meta-policy will be ignored.
  • none-this-response: This is a special meta-policy that can only be specified in an HTTP response header. It prevents this particular HTTP response from being interpreted as a policy file. Unlike all other meta-policies, none-this-response affects only a single HTTP response, rather than declaring an overall meta-policy for the entire server. Also unlike all other meta-policies, none-this-response can appear in combination with any other meta-policy without conflict. When none-this-response and another meta-policy are both present, then the current HTTP response will not be allowed to be a policy file, but the additional meta-policy will be interpreted to be the overall meta-policy for the server.
  • master-only: Only the master policy file located at /crossdomain.xml is allowed. This is the default setting for Flash Player 10 and later.
  • by-content-type: This setting is available only for HTTP and HTTPS servers. Only policy files served with the header Content-Type: text/[x-]cross-domain-policy are allowed.
  • by-ftp-filename: This setting is available only for FTP servers. Only policy files whose URLs end with /crossdomain.xml are allowed and no other policy files are allowed.
  • all: All policy files are allowed. This setting should only be used on public Internet servers that do not require login credentials. This is the current setting within Flash Player.

To utilize these controls, an administrator would create a crossdomain.xml file similar to the following example in their root web directory:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">
<!-- Policy file for mysite.com -->
<cross-domain-policy>
  <!--This is the only cross-domain policy file for this server -->
  <site-control permitted-cross-domain-policies="master-only"/>
</cross-domain-policy>

Alternatively, you can specify meta-policies within HTTP response headers. With the header mechanism, the meta-policy must be declared in every HTTP response. Meta-policies can be declared using the X-Permitted-Cross-Domain-Policies header, as follows:

HTTP/1.1 200 OK 
X-Permitted-Cross-Domain-Policies: none

This mechanism for meta-policies is not valid for FTP servers. If the none-this-response policy is being applied, then it may be necessary to send two policies. You can do this either by returning two headers or by using one header, separating the policies by a semicolon.

The meta-policy implementation is being back-ported to Flash Player 7 and Flash Player 8 to reach as many end-users as possible.

Initiating a policy file check

If you'd like to research the content discussed in this section further, you may find it useful to visit the following sections of the ActionScript 3.0 Language and Components Reference:

You can use the checkPolicyFile property to check for a policy file. There are checkPolicyFile properties for NetStream, SoundLoaderContext, LoaderContext and image tags in an HTML text area. This property is applicable to the Loader.load() method, but not to the Loader.loadBytes() method.

Set this property to true when you are loading an image (JPEG, GIF, or PNG) from outside the SWF file's domain, and you need programmatic access to the content of that image using ActionScript. Flash Player will first consider policy files that have already been downloaded, next it attempts to download any pending policy files specified in calls to the Security.loadPolicyFile() method, and then attempts to download a policy file from the default location that corresponds to URLRequest.url, which is /crossdomain.xml on the same server as URLRequest.url.

An example of accessing image content involves referencing the Loader.content property to obtain a Bitmap object, and calling the BitmapData.draw() method to obtain a copy of the loaded image's pixels. Attempts to utilize one of these operations without specifying a checkPolicyFile at loading time may result in a SecurityError exception because the needed policy file has not been downloaded yet.

The code example below illustrates how to check for policy files to avoid security errors:
// Setting a Loader to check the policy files
var ldr:Loader = new Loader();
var loader_context:LoaderContext = new LoaderContext()
loader_context.checkPolicyFile = true;
var url:String = "http://www.remote_example.com/content.swf";
var urlReq:URLRequest = new URLRequest(url);
ldr.load(urlReq,loader_context);
// Checking for a policy file by specifying "CheckPolicyFile" in an
// image tag defined within a TextArea
<img src = 'http://remote.server.org/filename.jpg'
checkPolicyFile = 'true' id = 'instanceName' >

SWF files are unable to check for cross-domain files if the allowNetworking parameter of the object and embed tags is set to false. If a SWF cannot locate the policy file, then a SecurityException will be thrown at the time a data load is attempted.

Socket policy files

Related threats: DNS rebinding, cross-domain privilege escalation

This section provides a brief summary of socket policy files. For complete information on socket policy files, please see Policy file changes in Flash Player 9 and Flash Player 10: Socket policy files and Setting up a socket policy server.

Socket policy files define what socket connections are permitted to the domain. Flash Player prevents attacks such as DNS rebinding by requiring the destination IP address to authorize the connection. In order to make a socket connection, Flash Player must first find a master socket policy file server listening on port 843 or a policy from the same port as the intended connection. Like master cross-domain policy files, master socket policy files support meta-policies to define where policy files are allowed on the server. The available meta-policies are:

  • all: Socket policy files are allowed from any port on this host. This meta-policy is appropriate only for hosts that are on the public Internet and do not serve any content that requires login credentials. This is the default.
  • master-only: Only the socket master policy file, served from port 843, is allowed on this host. The master socket policy file will define all of the allowed ports.
  • none: No socket policy files are allowed on this host. If this meta-policy is declared in the master policy file, then the master policy file is permitted to exist solely for the purpose of declaring this meta-policy, and any <allow-access-from> directives that it contains will be ignored.

If you specify a meta-policy of master-only, then all of the port permissions must be defined within the master socket policy file; any additional policy files that are loaded via loadPolicyFile() call will be ignored. If you specify a meta-policy of all, then this will allow you to host additional socket policy files on ports other than 843 or the destination socket. These socket policies can grant access to additional ports on the machine. However, there is one additional restriction: Policy files hosted on ports greater than 1024 can grant access only to other ports above 1024. A policy file returned from a port less than or equal to 1024 can allow access to any port. For instance, the master socket policy file is hosted from port 843 and can therefore allow access to all ports on the server.

Setting the secure flag

Socket policy files support a secure flag that is similar to HTTP policy files. Setting this flag to "true" within an <allow-access-from> directive informs Flash Player that only SWF files served over HTTPS are allowed to connect to the specified port. By default this flag is assumed to be false. It is currently not a best practice to rely on this flag for remote sockets since socket policy files are currently fetched over insecure protocols and are subject to man-in-the-middle attacks. Therefore, an attacker may change the value of the flag while it is transit. This flag may be appropriate for localhost connections where man-in-the-middle attacks are far less likely.

Use ranges and commas in a socket policy file to define port access

Instead of using wildcards to define port access, Flash Player will accept ranges and commas to specify groups of port numbers. This can reduce the risk of accidentally exposing non – Flash Player related ports to Flash Player's socket libraries:

// Use an XMLSocket request to port 843 in order to download a policy
// file allowing access to 456
System.security.loadPolicyFile("xmlsocket://socks.mysite.com:843");
// Connect to port 456
mySocket.connect("socks.mysite.com", 456);
// The crossdomain.xml file on port 123 allowing access to 456
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">
<!-- Policy file for xmlsocket://socks.mysite.com -->
<cross-domain-policy> 
   <!-- This is a master-policy file -->
   <site-control permitted-cross-domain-policies="master-only"/>
   <!-- Instead of setting to-ports="*", administrator's can use ranges and commas -->
   <!-- This will allow access to ports 123, 456, 457 and 458 -->
       <allow-access-from domain="socks.mysite.com" to-ports="123,456-458" />
</cross-domain-policy>