This section discusses a number of differences in the security model implementations when running content within Adobe AIR, versus running it in the browser.
Adobe AIR enables Ajax and Flash/Flex developers to use their existing skills to build and deploy desktop applications. Although these applications are built using web technologies, the key thing to keep in mind is that the end result is targeted for running on desktop, and thus the security model for AIR is much closer to that of a desktop application than of a web application.
A desktop application has high privileges compared to a web application as it is installed by the user on a specific machine, implying a degree of trust that is greater than that of arbitrary web content. Unfortunately there are design and implementation patterns common to web applications that can be dangerous when combined with the local system access or other AIR APIs available.
The runtime provides a comprehensive security architecture that defines permissions according to each file in an AIR application. Permissions are granted to files according to their origin, and are assigned into logical security groupings called sandboxes.
The application sandbox provides access to all Adobe AIR APIs, including those that provide access to the user's system.
When an application is installed, all files included within an AIR installer file are copied onto the user's computer into an application directory. Developers can reference this directory in code through the app:/ URI scheme. All files within the application directory tree are assigned to the application sandbox when the application is run.
When running within the application sandbox, some potentially dangerous patterns that are allowed in the browser, are restricted. The things that are disabled revolve around the importing of remote JavaScript content and the dynamic execution/evaluation of JavaScript strings.
NOTE
Please see the Adobe AIR documentation for a complete list of what is and is not allowed within the application sandbox.
The non-application sandbox contains all content that is not loaded directly into the application sandbox. This may include both local and remote content loaded into the application at runtime. Such content does not have direct access to AIR APIs and obeys the same rules that it would have to obey in the browser when loaded from the same location (for example HTML from a remote domain behaves like it would behave in the browser). Because this content doesn't gain direct access to AIR APIs it can call into any code evaluation technique that works in browser, such as eval, loading remote scripts, etc.
Access to the runtime environment and AIR APIs are only available to HTML and JavaScript running within the application sandbox. At the same time, dynamic evaluation and execution of JavaScript, in its various forms, is largely restricted within the application sandbox. These restrictions are in place whether or not your application actually loads information directly from a remote server.
Here's an overview of the differences you may run into when coding for application sandbox.
In general, code evaluation restrictions do not apply while code is initializing prior to the onload event. Strings can be turned into executable code via the use of eval or the Function constructor, and attributes are turned into actual event handlers such as:
<input type="button" onclick="doClickBtn();"/>
NOTE
If code execution is prevented due to sandbox security restrictions, the following JavaScript error will be thrown : "Adobe AIR runtime security violation for JavaScript code in the application security sandbox."
HTML files running in application sandbox (loaded from the installed directory of the application) can only import JavaScript files located in the same installed directory via
<script src="file.js" type="text/javascript"></script>
If you must load remote JavaScript, you must either install the file(s) with the application or load it into the non-application sandbox.
Code running in the application sandbox can load data from any remote domain via XMLHttpRequest. There is no cross domain policy enforced for the code loaded from the application install directory, as there is no domain associated with this code (it uses the AIR specific app:/ scheme to load the files from the installation directory). However, the tradeoff is that the content loaded via XHR can only be used as data; it cannot be transformed into executable code (with one exception explained below).
APIs which allow dynamically generated code to execute are prohibited after the onload event. The table below shows which APIs are restricted when running within the application sandbox:
Everything that is not loaded from the application install directory is loaded into the non-application sandbox.
Code in the non-application sandbox does not have direct access to AIR APIs, and thus does not have the JavaScript code evaluation restrictions applied to it.
When a file loaded from the application sandbox loads a file from a non-application sandbox (either via the iframe or frame tags, or from opening a new window) the loaded content will be placed within the non-application security sandbox, with no direct access to AIR apis.
Adobe AIR also provides a way to load application content into the non-application sandbox. This is done via the sandboxRoot and documentRoot properties on the iframe and frame tags.
<iframe
src="ui.html"
sandboxRoot="http://www.example.com/airapp/"
documentRoot="app:/sandbox/">
</iframe>
This example maps content installed in the "sandbox" subdirectory of the application to run in the remote sandbox bound to www.example.com domain.
The sandboxRoot property specifies the URL to use for determining the sandbox and domain in which to place the iframe content. The file:, http:, or https: URL schemes must be used.
The documentRoot property specifies the directory from which to load the iframe content. The file:, app:, or app-storage: URL schemes must be used.
XMLHttpRequest
Code in the non-application sandbox is bound by a same-origin policy and, by default, cannot do cross-domain data loading via XMLHttpRequest from any remote URL.
However, this behavior can be overwritten by setting the allowCrossDomaininXHR attribute to true on the iframe or frame element loading the content.
window.open
The window.open() api only works if it's a direct result of user interaction (such as mouse click or keypress).
Window term
The title of a window opened by non-application content is prefixed with the application title (to prevent windows opened by remote content from spoofing windows opened by the application).
The runtime lets you create an interface called Sandbox Bridge between content in a non-application sandbox and its parent document in the application sandbox. This is a bi-directional serialization API designed to allow domains/sandboxes that otherwise cannot trust each other entirely to interact.
It is possible for the developer to provide a bridge between application sandboxed content (parent) that loads content (child) into the non-application sandbox. Essentially, the parent can explicitly allow the child to access specific properties and methods that it defines.
The application sandbox content (parent) can set up a property called parentSandboxBridge on the frame or iframe tag, and expose functions by attaching them to this property. These functions can be accessed by the non-application content inside the iframe or frame.
In a similar way, the non-application sandbox—the child—can set up a property called childSandboxBridge on its window object and expose functions to the application sandbox.
In order for a script in a child document to access a function attached to the parentSandboxBridge property, the bridge must be set up before the script is run. A new AIR-specific event called dominitialize is fired when the DOM has been created, but before any scripts have been parsed, or DOM elements added. You can use the dominitialize event to establish the bridge early enough in the page construction sequence that all scripts in the child document can access it. Here is an example:
parent.html
<html>
<head>
<script type="text/javascript">
var bridgeInterface = {};
bridgeInterface.testProperty = "Bridge engaged";
bridgeInterface.testFunction = function() { alert
('testFunction') };
function setupBridge(){
document.getElementById("sandbox").contentWindow.
parentSandboxBridge =bridgeInterface;
}
</script>
</head>
<body>
<iframe id="sandbox"
src="http://www.example.com/airapp/child.html"
documentRoot="app:/"
sandboxRoot="http://www.example.com/airapp/"
ondominitialize="setupBridge ()">
</iframe>
</body>
</html>
child.html
<html> <head> <script type="text/javascript"> alert(window.parentSandboxBridge.testProperty); </script> </head> <body></body> </html>
As a general rule, you should not directly expose AIR apis to content running in the non-application sandbox, but rather should encapsulate the access via a function. This ensures that only specific AIR APIs can be called, and when they are called, are only executed in the manner that you allow.
| Capability | Application sandbox | Non-application sandbox |
|---|---|---|
| Direct access to AIR APIs | Yes | No |
| Access to application sandbox functions that use AIR APIs via the SandboxBridge | N/A | Yes |
| Loading remote JavaScript files | No | Yes |
| Can, by default, execute cross-domain requests (XHR) | Yes | No |
| Supports transforming strings into executable code after the onload event | No | Yes |
| Ajax frameworks work by default | No[1] | Yes |
[1] Frameworks must add support for Adobe AIR.
For more details on working with the Sandbox Bridge see: http://www.adobe.com/devnet/air/ajax/quickstart/sandbox_bridge.html