allowScriptAccess Default

July 27th, 2006 by Posted in Macromedia Flash, Macromedia Flash Player

   

allowScriptAccess Default

Flash Player has supported an HTML parameter called allowScriptAccess since version 6. This parameter controls whether ActionScript in a SWF is permitted to call JavaScript in the HTML page that contains it. (It does not control the reverse, where JavaScript calls ActionScript—that is governed by System.security.allowDomain.)

The possible values of allowScriptAccess are as follows:

  • always: Always permit ActionScript-to-JavaScript calls
  • sameDomain: Permit ActionScript-to-JavaScript calls only when the SWF and HTML page come from the same domain
  • never: Never permit ActionScript-to-JavaScript calls

In Flash Player 6 and 7, the default value for allowScriptAccess (when not specified by the HTML page) was “always.” Separately, the default value for allowScriptAccess in the Flash HTML publish templates has always been “sameDomain.” If you leave the output from the Flash HTML publishing process unmodified, you will see “sameDomain” behavior because your HTML page will be specifying “sameDomain” to Flash Player.

In Flash Player 8, the default for an unspecified allowScriptAccess value remains “always” when the main SWF in Flash Player is version 7 or earlier, but changes to “sameDomain” when the main SWF is version 8 or later.

The allowScriptAccess parameter allows an HTML page to include Flash content but prevents it from executing scripts in the HTML page. This can be useful when an HTML page sources Flash content that it may not trust. For example, if you maintain a forum where users may include SWF signatures of their own making, and your generated HTML will directly source these SWFs, then you probably do not want these SWFs to be able to execute scripts in your HTML page.

Here is an example of how allowScriptAccess is specified:

      classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/
flash/swflash.cab#version=8,0,0,0"
width="375" height="300">


pluginspage="http://www.macromedia.com/go/getflashplayer"
type="application/x-shockwave-flash"
src="hello.swf"
width="375" height="300"
allowScriptAccess="sameDomain">

Note: The allowScriptAccess parameter cannot be used to work around the new Flash Player 8 restrictions on SWF-to-HTML communication involving local SWF and HTML files. The allowScriptAccess parameter mainly controls the right of remote SWFs to access remote HTML pages. In a few cases, allowScriptAccess permits SWF-to-HTML communication involving certain types of local files. For example, a trusted local HTML file may permit an untrusted local SWF to script it by setting allowScriptAccess="always". However, an untrusted local HTML file may never permit an untrusted local SWF to script it, regardless of the value of allowScriptAccess.

allowDomain Wildcard Support

Note: The changes described in this section apply to both System.security.allowDomain() and System.security.allowInsecureDomain(). For clarity, only System.security.allowDomain is described; the changes to System.security.allowInsecureDomain() are identical. Macromedia does not recommend calling System.security.allowInsecureDomain() because it weakens the security provided by SSL (HTTPS).

Starting with Flash Player 8, System.security.allowDomain() accepts a single asterisk, “*”, as a wildcard. Calling System.security.allowDomain(“*”) has the effect of permitting scripting access by other SWFs from all domains, not just those from a specific domain.

This wildcard permission is convenient if you are in a situation where you do not have sensitive data to protect and you need to share data openly with other domains. Before calling System.security.allowDomain(“*”), however, be sure the calling SWF does not contain any information or ActionScript code that needs to be kept private or semiprivate. Once you call System.security.allowDomain(“*”), any SWF from anywhere on the Internet can load your SWF and script it—even SWFs written by malicious authors.

Note that you might occasionally have to call System.security.allowDomain() in a situation where you don’t know the domain from which the cooperating SWF will be served until runtime, perhaps because the cooperating SWF is being served from a load-balancing cluster or because your SWF will be used on many different domains. In this situation, do not call System.security.allowDomain(“*”) blindly! As just mentioned, this will open your SWF to scripting by absolutely any other SWF on the Internet. Instead, wait until the cooperating SWF is loaded and then determine its domain using the ActionScript property MovieClip._url. After you pass the value of the _url property to System.security.allowDomain(), the SWF in the referenced move clip should then be able to script the SWF that called System.security.allowDomain().

Flash Player 8 permits SWFs of any version to pass “*” to System.security.allowDomain(). However, if you are going to call System.security.allowDomain(“*”) in a SWF with a version less than 8, be sure to test that the player version (System.capabilities.version) is at least 8 before doing so because earlier versions of Flash Player will not recognize “*” as an argument to System.security.allowDomain.

More Precise Permissions

Note: The changes described in this section apply to both System.security.allowDomain() and System.security.allowInsecureDomain(). For clarity, only System.security.allowDomain is described; the changes to System.security.allowInsecureDomain() are identical. Macromedia does not recommend calling System.security.allowInsecureDomain() because it weakens the security provided by SSL (HTTPS).

When you call System.security.allowDomain(), two parties are involved in the permission that is established: the granting party, which is the SWF that calls System.security.allowDomain(), and the using party, which is the domain that is specified in the argument to System.security.allowDomain(). Once this permission is established, any SWF from the using domain can script the granting SWF.

In Flash Player 6 and 7, any SWF from the using domain could script not only the granting SWF itself but also any SWF from the domain of the granting SWF. The granting party was considered a granting domain rather than a granting SWF. For example, if a SWF from http://site1.com/app1.swf called System.security.allowDomain(“site2.com”), then a SWF from http://site2.com/another.swf could script either the granting SWF, from http://site1.com/app1.swf, or any other SWF loaded from site1.com, such as http://site1.com/different.swf.

This arrangement could occasionally produce surprising results. A maintainer of site1.com might manage many different Flash applications that had nothing to do with each other, and it might be necessary for certain of those applications to allow access by an outside domain, but undesirable for all applications on site1.com to allow that access. The author of app1.swf might not have realized that, by calling System.security.allowDomain(“site2.com”), they were allowing access to not only app1.swf but also different.swf.

When a SWF of version 8 or later calls System.security.allowDomain(), the calling SWF is the only granting party. If two different SWFs from the same domain both wish to allow access by an outside domain, each SWF that wants to allow the access must call System.security.allowDomain().

This behavior applies only to SWFs of version 8 or later. SWFs of version 6 or 7 that call System.security.allowDomain(), even when playing in Flash Player 8, will still grant access to all version 6 and 7 SWFs in their own domain in order to preserve backward compatibility. However, a version 6 or 7 SWF that calls System.security.allowDomain() will not grant access to SWFs of version 8 or later in its own domain.

The same change in behavior has been made for System.exactSettings, which determines whether a SWF will use its Flash 6-style superdomain (for example, mysite.com is the superdomain of www.mysite.com) or its Flash 7-style exact domain (for example, www.mysite.com) as a basis for camera/microphone permissions and persistent shared objects. In Flash Player 7, if one SWF in a domain changed the value of System.exactSettings, that change applied to all SWFs from the same domain. In SWFs of version 8 or later, setting System.exactSettings affects only the calling SWF.

Secure Persistent Shared Objects

In Flash Player 8 and later, a SWF that originates from an HTTPS URL may specify, when reading or writing a persistent shared object, that it wishes to use a separate store of shared objects that is accessible only to SWFs that are served over HTTPS. Such shared objects will not be susceptible to the hypothetical attacks described below. Other than the HTTPS requirement, the rules for access to shared objects in the secure store are the same as the rules for non-secure shared objects: By default, only a SWF from the same URL as the original creator may access the shared object but if the creator specified a localPath option shorter than its full URL, then other SWFs whose URLs begin with that same prefix may also access the shared object by specifying the same localPath.

Retrieving a Secure Shared Object

To retrieve a secure shared object, pass a true value for the new, optional parameter called secure to SharedObject.getLocal() or SharedObject.getRemote():

static function getLocal(name:String, 
localPath:String,secure:Boolean) : SharedObject;
static function getRemote(name:String,
remotePath:String, persistence:Object,
secure:Boolean) : SharedObject;

(Note that remote shared objects require Flash Media Server and are documented only with that product.)

For example, to retrieve a secure local shared object:

var mySO = SharedObject.getLocal("userInfo", null, true);            

(The null value for localPath has the same effect as omitting localPath entirely, so pass null for localPath if you want a secure shared object with the default localPath.)

Note that the secure flag defaults to false, meaning that no SWFs created prior to Flash Player 8 will be affected by this new feature—only SWFs that specifically request secure shared objects will use the new, separate secure store. All shared objects created by earlier SWFs, whether HTTPS or not, reside in the original, non-secure store.

If a SWF from a non-HTTPS URL passes true for the secure parameter, the getLocal() or getRemote() call will return null.

Be aware that secure and non-secure shared objects come from entirely separate spaces, so it is possible to obtain two persistent shared objects (one secure and one non-secure) that have identical names, localPaths, and domains but are separate. For example, if an HTTPS SWF creates a secure shared object called “userInfo” and a localPath of “/”, and later an HTTP SWF retrieves a non-secure shared object called “userInfo” and a localPath of “/”, this second shared object will actually be separate from the first because the two objects come from different stores.

Why Use Secure Shared Objects?

Secure persistent shared objects provide protection against a hypothetical class of attempts by unauthorized parties to access sensitive data.

The HTTPS protocol provides several important protections. The best-known of these is encryption, which prevents third parties on the network from seeing the contents of the network conversation. But another important benefit is integrity, which ensures that when one party sends data to the other, the data either arrives without modification or, if it arrives modified, the modification is detected and the data is rejected as invalid. This helps thwart what is called a man-in-the-middle attack, which takes advantage of the Internet’s distributed nature: a party in the middle of the network conversation, such as an employee of an ISP, a network operator, a proxy server, a firewall, and so on, can not only listen in on a conversation but can modify data sent in either direction, possibly inserting their own document that takes actions on the sending party’s behalf that the sending party did not intend. For example, if a user visits example.com and views a SWF that asks for login information, a man-in-the-middle attacker could substitute his or her own, nearly identical SWF that would not just send the user’s login to the intended recipient but also send it to the attacker. If, however, the connection is secured over HTTPS, a middle party’s modified SWF would be rejected when the client received it and the attack would fail.

For completeness’ sake, another similar attack is based on impersonation of a site providing a SWF, using vulnerabilities in DNS or other systems that are used to identify a server. Another property of HTTPS called authentication foils this type of attack by using SSL certificates to verify the identity of the server. For our purposes, discussing a man-in-the-middle attack suffices to cover both man-in-the-middle and impersonation attacks.

If you serve a SWF over HTTPS and you write a persistent shared object from that SWF, you may have good reasons to want the data in that shared object to remain available only to your own SWFs—and, essentially, to the user. For example, you may be recording sensitive information in a persistent shared object, such as account information or financial data. Ideally, for instance, you would like to be sure that if one of your users falls victim to a man-in-the-middle attack, the attacker cannot gain access to the data in that shared object.

In Flash Player 7, if your HTTPS SWF wrote a shared object and a user was subsequently tricked by a man-in-the-middle attacker into visiting an URL on your site from which the shared object could be accessed—in fact, possibly the very same URL from which your SWF was served—but with the crucial difference of using HTTP instead of HTTPS, then the attacker could send their own SWF and Flash Player would believe that the attacker’s SWF came from your site. The attacker’s SWF would then be able to read the shared object and report its contents back to the attacker.

To be sure, these attacks are difficult to orchestrate. If you have already deployed HTTPS SWFs that have written sensitive data in persistent shared objects, it is not very likely that anyone has attempted to access your data using attacks of this type. However, for optimal protection in the future, if you store sensitive data in persistent shared objects, you should consider using secure shared objects.

Where to Go from Here

As one of the most widely distributed pieces of software in the world, Flash Player earns its place on so many computers and devices by virtue of its rich media capabilities, stability, and trustworthiness. In addition to new expressive capabilities and improved performance, Flash Player 8 enhances the web-surfing safety of its hundreds of millions of users. That fact will not go unnoticed. Flash Player will keep its reputation among security professionals as responsible software that puts users in control of their personal information.

The enhancements discussed in this article are not entirely without cost. A small fraction of the millions of SWFs that circulate through the world will, quite unintentionally, be affected by these new user protections in ways that their authors could not originally have foreseen. Macromedia does not take such developments lightly—we have spent considerable time weighing the costs and benefits of these security changes. Flash has built a strong reputation as a “deploy once and never worry again” technology. New Flash Player releases play even the oldest Flash content just as well as when it was first published. Nevertheless, we stand by our responsibility to Flash Player users. In making Flash Player worthy of everyone’s trust, we will guarantee a long, stable future for rich media.

  •  

  •    
  •