" /> State of Security: July 2007 Archives

« June 2007 | Main | October 2007 »

July 30, 2007

AIR Install Experience

If you haven't gotten your personal dose of AIR yet, check it out at http://labs.adobe.com/technologies/air/

The install experience for an AIR application has been the subject of much effort internally, and many questions externally. One of the common questions revolves around the relatively "scary" nature of the installation dialogs.

One of the goals of the installation experience is to accurately communicate to the user the potential risk of installing AIR applications in general. An AIR application is a fully privileged local application, with similar powers and risks to a native application--including full filesystem read/write access. As such, the danger is that developers, IT administrators, or users could assume that AIR applications are somehow intrinsically "safer" to install since they are based upon web technologies.

One way a developer can improve the installation experience for the user is to sign the AIR installer file with a commercial code signing certificate. To see the difference in the installation experience for such an application, check out the "Employee Directory" sample AIR application here: http://labs.adobe.com/technologies/air/samples/

In the future there may also be more restrictive sandbox types that provide a "safer" type of AIR application, with a corresponding installation experience to encourage developers to develop applications with the minimum level of necessary privilege.

Flash Media Server, RTMP and Sandboxing

In response to previous questions regarding FMS security, the reasoning behind the restrictions on interacting with RTMP streams is to protect the content being provided by the server. This is a little different from other data loading operations as RTMP is not directly covered by cross-domain policy files and was not originally intended as an interactive data source (rather than just a hands-off media type).

In theory permitting access to the RTMP stream does not pose security issues so long as the Flash Media Server can reliably specify a preference for who is permitted to interact with the RTMP streams. So don't be surprised if this restriction is relaxed in the future.

For detailed information regarding protection content served from Flash Media Servers, see http://www.adobe.com/devnet/flashmediaserver/articles/protecting_video_fms.pdf

July 10, 2007

How to restrict SWF content from HTML

When you host SWF content inside HTML, you have a few tools at your disposal to control how much privilege that SWF has. If you are hosting SWFs that you created or trust completely, these may be unnecessary, however you may find them useful otherwise.

When specifying container tags (i.e. OBJECT or EMBED), you can optionally provide one of the following two parameters: "allowScriptAccess" and "allowNetworking". These tags can only be specified within HTML (not from a SWF itself), and apply to that root SWF and any other SWFs the root SWF may load.

"allowScriptAccess" controls the ability of the SWF to call into the browser's JavaScript DOM. This means the SWF could inject script into the website that is hosting it, which can be either dangerous, or at least not desirable (as the SWF could open new windows, inject JavaScript into the surrounding HTML, redirect the current window, read cookies, etc.)

"allowNetworking" affects the ability of a SWF to perform network I/O, either via the browser (opening new windows, etc.) or directly using Flash networking APIs. This implicitly may also restrict scripting access to the browser, as you cannot prevent network I/O without prohibiting access to the browser's JavaScript DOM.

In order of least to most restrictive, you can specify:

"allowScriptAccess=always": This permits the SWF to call arbitrary browser JavaScript at all times, even if the SWF came from another domain. This is generally not safe to do unless you completely trust the SWF you are loading (and any children SWFs it may subsequently load).

"allowNetworking=all": All normal network I/O is allowed (as permitted by the Flash Player security model).

"allowScriptAccess=sameDomain": This permits the SWF to call into the browser's JavaScript DOM only if the SWF came from the same domain as the HTML hosting it. This is equivalent to the typical browser "same origin policy" model.

"allowScriptAccess=never": The SWF is never permitted to call into the browser's JavaScript, even if it came from the same domain as its HTML container. You can use this tag if you host SWFs in the same domain as the HTML, but don't trust the SWFs to interact with the surrounding HTML, cookies, etc. In particular this setting will also prevent the SWF from modifying or redirecting existing frames windows. However, if you really don't trust the SWF you may need some stronger medicine.

"allowNetworking=internal": Everything with "allowScriptAccess=never" applies, and also prevents the SWF from opening new browser windows, modifying existing ones, or otherwise affecting any browser state. The SWF can still use internal networking ActionScript APIs like loadMovie(), XML.load(), LoadVars, etc.

Finally, "allowNetworking=none" prohibits any browser or network interaction. This means that the SWF cannot do much more than interact with the assets it contains internally, and cannot do anything to influence the browser, or load or send any data over the network.

In addition, Flash Player integrates with the browser's pop-up blocking technologies to ensure that windows that could not be opened directly via HTML/JavaScript will be blocked in Flash as well.

The safest strategy is to always explicitly set the parameter value you want, so you don't have to worry about what the behavior will be on a given situation.

For additional details on the allowScriptAccess tag, see http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000360.html

For additional details on the allowNetworking tag, see http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000360.html

July 09, 2007

Cross-domain policy files

Today I'd like to take a shot at summarizing the reasoning behind having cross-domain policy files in Flash Player, and some best practices related to implementing them.

The browser security model normally prevents web content from one domain from accessing data from another domain. This is commonly known as the "same origin policy." Note that this policy does not prevent the displaying of HTML or media assets cross-domain, such as HTML in an IFRAME or other images, etc. This is also true in Flash Player.

So how did cross-domain policy files in Adobe Flash Player come about? The rationale is that sometimes its perfectly ok to permit cross-domain loading of data, such as when the data isn't protected by a session-based login or a firewall, and is intended to be accessible from other websites. Currently, the only way to do this inside JavaScript is by using the <SCRIPT src=...> script importing syntax, which is inherently dangerous.

By providing a cross-domain policy file, a website can specify which parts of it should be accessible, and to content from which other websites. If a cross-domain policy file is located at the root of the website (the default location the Flash Player looks in for cross-domain policy files is "/crossdomain.xml"), then it controls access to the entire site. If it is placed in a sub-directory, it only controls access to that subdirectory and below.

So if your website hosts only data intended for public consumption, isn't behind a corporate firewall, and does not protect any data via cookies or other browser-based user authentication mechanisms, then you can deploy a policy file that permits access from "*" (anywhere) in your root folder.

If you want to permit content from only certain websites to load data from a given server, then you could specify only those websites in your policy file. For example, if http://www.a.com and http://www2.a.com need to load data from http://data.a.com , then you would create a policy file at http://data.a.com/crossdomain.xml that would include "www.a.com" and "www2.a.com", or alternatively, simply "*.a.com". The server that is providing the data always hosts the policy file that controls access to its data. No other server can do so on its behalf. Here is an example crossdomain.xml:

<?xml version="1.0"?>
<!-- http://www.adobe.com/crossdomain.xml -->
<cross-domain-policy>
<allow-access-from domain="www.a.com" />
<allow-access-from domain="www2.a.com" />
</cross-domain-policy>

If on the other hand you want to only expose specific parts of your website to the whole world, then you can place a policy file containing "*" in the specific subdirectories that you want to expose to the world. You may also expose certain subdirectories only to content from specific servers, etc. The principle of least privilege implies that you should only expose the parts of your website that you really need to, and only to the minimum number of other websites.

The general best practice for deploying policy files is to have separate servers. One, such as http://www.a.com, as a regular web server without any cross-domain policy files, and then another, one such as http://api.a.com, that hosts only data intended for public consumption and does not utilize any browser-based (i.e. cookies) user authentication mechanisms.

There are many other permutations of this mechanism, that may or may not be applicable to your particular architecture.

For example usage of cross-domain policy files, see: http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001085.html

For a detailed description of cross-domain policy file best practices, see: http://www.adobe.com/devnet/flashplayer/articles/cross_domain_policy.html

July 08, 2007

Scheming

In the realm of security, "trust" is generally defined as "something acting the way you expect it to act." By that definition, URI schemes (http://en.wikipedia.org/wiki/URI_scheme) have a checkered history at best.

Many developers tend to assume that a URL simply refers to a network data loading protocol, such as HTTP, HTTPS, and FTP. However, it been extended over time to include:
- local file I/O (file:)
- network file I/O (smb:, nfs:)
- local application integration (mailto:, various IM & streaming media schemes)
- local operating system integration (generally very dangerous stuff like shell:, vshelp:, local:)
- actual code generation/injection schemes that can create JavaScript within the browser (javascript:, data:).

Flash in particular also supports the asfunction: scheme, which can be used to call local ActionScript functions within your SWF.

If you are building an application that handles URLs, you should be aware of your responsibility to ensure that any URLs that are passed to the application and acted upon--either by having the application loading it directly or by the user clicking on it--are handled appropriately.

The best way to do so is to enforce a whitelist. That is, identify which schemes your application should permit and deny everything else. For example, if your goal is to permit people to link back to their blogs or other websites, you may want to only permit URLs that begin with "http://" and "https://". If you'd like to also allow people to subscribe to link to streaming music or videos, or click on emails, you can add the relevant schemes to the whitelist.

The other alternative is to implement a blacklist, which means to identify only the bad schemes you want to block and permit everything else by default. This is problematic for a few reasons. First of all, it can be difficult to catch all permutations of escaping and encoding of scheme names, so its often possible to fool blacklists. This can be as simple as just using URL-encoding on one or more characters in the scheme name, for example using "javascript%3A" instead of "javascript:". These attacks get dramatically more complex from there, so I won't try to exhaustively list them here.

But even worse is the problem of actually identifying all of the untrustworthy schemes (untrustworthy being defined as acting in a manner undesirable or otherwise unexpected given your application). You can start by looking at the list of know schemes here: http://en.wikipedia.org/wiki/URI_scheme#Official_IANA-registered_schemes and http://esw.w3.org/topic/UriSchemes/.

But suffice it to say, be careful when processing any data that contains URLs, and don't just rely on the browser to protect your applications.