12 September 2005
Intermediate
Note: This article describes the security features in Flash Player 8. It is intended for historical purposes only. To remain up to date about Flash security, please read the latest security documents in the Flash Player Developer Center.
Flash Player 8 changed the security model that's applied to local Flash content. By default, Flash applications that are run from a user's local file system rather than over HTTP have more limited privileges in Flash Player 8 than in Flash Player 7. This model is applied to Flash content of all versions, which means that content published before the release of Flash Player 8 may be affected, in addition to new content created after its release. This article describes how to fix most issues that arise from these changes.
Besides changes to the security model, Flash Player 8 introduced a few other restrictions and adds some new security features. This article describes those changes as well, but the local security changes are by far the biggest security topic in Flash Player 8.
Note: These local security changes do not affect Flash content served over HTTP. Most Flash content is served over HTTP and should be unaffected by these changes.
Here are the limitations on what Flash content can do:
Here is the security functionality available to Flash content (for security information about Flash Player 7, please refer to Security changes in Flash Player 7):
The local security changes in Flash Player 8 are motivated by one main concern: When users download SWFs to their computers, they should be able to trust that Flash Player will not permit those SWFs to take any harmful actions against them. Wherever security is concerned, users should feel as confident downloading and running SWF files on their computers as they do storing JPEGs or TXT files, rather than having to be cautious, as they must be with executable files.
Up through Flash Player 7, the treatment of local SWFs was motivated by the meaning of a local SWF for an author of Flash content: A local SWF is usually just a temporary local file that is intended eventually to be published on the web. In this context, there is no need to restrict what local SWFs can do. However, when a SWF is downloaded and run by a user who is not a Flash author, the user may not have sufficient knowledge of the SWF's origin to trust that its intentions are honest. In Flash Player 7 and earlier, if a malicious party managed to convince a user to download and run a SWF, that local SWF would be able to combine two privileges to ill effect: It could read text files from known (or guessed) locations in the user's filesystem—using, for example, XML.load()—and then send the contents of those files back to the attacker. It is this file-snooping pattern that the local security changes in Flash Player 8 are designed to prevent.
A huge factor in the long-term success of Flash has been the tendency for all new releases of Flash Player to be backward-compatible with all existing Flash content. Security changes sometimes violate this principle, frustrating Flash developers and users alike. (Many readers will probably recall the content changes required by the security changes in Flash Player 7.) We are aware of the impact these changes have on our customers and we do not undertake such projects lightly. We offer our sincere apologies if you find yourself affected.
Despite these challenges, improving our security model is the right course for a platform technology like Flash. Flash Player enjoys incredibly broad distribution, which is a crucial part of the value of Flash to customers. Secure behavior is a requirement if we want users and businesses to continue installing and upgrading Flash Player. In hindsight, things might have been easier had we devised a more secure set of rules for local Flash content earlier in the history of Flash Player. However, security threats evolve, as do our customers' uses of Flash, and it sometimes takes multiple releases to get something right.
The good news is that much less content should be affected by the changes in Flash Player 8 than was affected by the changes in Flash Player 7. The changes in Flash Player 7 affected some content that was deployed on the web, whereas the changes in Flash Player 8 affect only content that is deployed as local files, which is considerably less common. With Flash deployments numbering in the millions worldwide, "less common" still means there are plenty of examples of locally deployed Flash content out there, but we expect many fewer developers to be affected than were affected by the Flash Player 7 changes.
In Flash Player 7 and earlier, local SWFs—those loaded from a user's filesystem using a local path—were freely permitted to perform most of the operations normally governed by Flash Player security rules. For example, while a SWF loaded over HTTP is only permitted (by default) to load text using XML.load() from its own origin domain, a local SWF in Flash Player 7 was permitted to load text from any HTTP URL, or any local filesystem path, using XML.load().
Think of reading a text file from a local path as a privilege called local-read. Consider also that, in Flash Player 7, all SWFs had an additional privilege called net-send, which enables any data to be sent to any Internet location using, for example, an HTTP POST operation via LoadVars.send(). Combine local-read and net-send in a local SWF that an end user has downloaded from an untrusted source and you can see that the local SWF could take the inappropriate step of reading text files off the user's computer and sending their contents back to a location on the Internet, all without the user's knowledge.
In Flash Player 8, the simplest summary of the rules for local SWFs is this: By default, local SWFs retain the local-read privilege but lose the net-send privilege; they are not permitted to communicate with the Internet (or any HTTP server) in any way. By changing a setting in a SWF file, a Flash author can elect to have a SWF gain the net-send privilege, in return for giving up the local-read privilege. Finally, authors and users can configure Flash Player to elevate a SWF to a trusted status where it has both privileges—in other words, the SWF will have exactly the privileges it had in Flash Player 7.
Flash content may be affected depending on two factors: whether it is local content and in which type of Flash Player it is being executed.
Affected SWFs are those loaded from local paths. This includes the following examples of URL forms (among others):
There are several different Flash Player types and each is affected in different circumstances:
In Flash Player 8, all SWFs (and HTML files, for purposes of SWF-HTML scripting) are placed into one of four types of sandbox:
It may be helpful at this point to look at the appendix of diagrams describing local security (see the section, Local Security Diagrams).
If a local SWF needs access to the Internet (or an intranet HTTP server), there are two local sandboxes that offer such access. The local-with-networking sandbox is more easily achieved, and all necessary configuration conveniently travels with the SWF itself. The local-trusted sandbox is more powerful, offering greater privileges, but generally takes more effort to achieve and requires configuration information that is separate from the SWF itself. After explaining the details of the local security rules, this article will return to the question of how to decide between these two alternatives.
Because local files no longer have unrestricted permissions in Flash Player 8, there are situations where Flash permissions may be granted to local files. These are described in the next section.
In general, Flash Player adheres to a principle of requiring global permissions in order to grant permissions to local files. For example, if a remote SWF wishes to permit itself to be scripted by a local-with-networking SWF, it must call System.security.allowDomain("*"), thus permitting any other loaded SWF to script it. Flash Player does not offer any way to grant permission only to local files; the granting party must be willing to grant permission to all files. This is because Flash Player cannot determine an origin for any local file—the file could have come from anywhere. It is thus not appropriate to permit a local file to perform an action unless the granting party does not care where the file came from.
Be sure not to call System.security.allowDomain("*") unless the SWF that does so contains no sensitive information. Do not simply call System.security.allowDomain("*") as a cure-all for your security problems—doing so sacrifices protections that your content may need! Take some time to think about the consequences of granting global permissions each time you do so.
This section describes the various local sandboxes into which SWFs are placed.
Flash Player defines the following types of privileges for local files:
fscommand
getURL("javascript:...")
ExternalInterface.call
The JavaScript API (SetVariable, GotoFrame, and so on)
Calling a callback established with ExternalInterface.addCallback
A local SWF is placed in this sandbox if it contains a flag called UseNetwork. This flag can be placed in a SWF of any version, although it is meaningful only to Flash Player 8 and later. This flag is established in one of two ways:
Note that the UseNetwork flag does not affect SWFs that are loaded over HTTP—these are always placed in remote sandboxes—or that have been trusted by the user—these are always placed in the local-trusted sandbox. The UseNetwork flag only affects SWFs that would otherwise be placed in the local-with-filesystem sandbox.
A local SWF (or HTML file) is placed in this sandbox if it falls under a local path that has been designated as trusted in the user's local configuration. Paths to individual files can be trusted, or directories can be trusted, resulting in all files in each selected directory and any of its subdirectories being trusted. Trust designations can be achieved in two ways:
Users may also make a global decision about how Flash Player should handle older SWFs (local-with-filesystem SWFs of version 7 and lower) using the "Ask/Allow/Deny" options in this panel. The default here is "Ask," which fails any prohibited operations but shows the warning dialog box. Choosing "Always allow" instead allows prohibited operations to succeed, thus reverting to the default behavior of Flash Player 7. However, this setting does not affect SWFs of version 8 or higher; it is only intended to affect content that was developed before the newer local rules were made. Choosing "Always deny" causes all prohibited operations to fail without showing the dialog box.
Note: The Ask/Allow/Deny options govern not only local security prompt situations but also the exact domain match prompt situations that have occurred since Flash Player 7.
<system>\Macromed\Flash\FlashPlayerTrust
(e.g. c:\WINNT\system32\Macromed\Flash\FlashPlayerTrust)
<app data>\Macromedia\Flash Player\#Security\FlashPlayerTrust
(e.g. c:\Documents and Settings\fred\Application Data\Macromedia\Flash Player\#Security\FlashPlayerTrust)
<app support>/Macromedia/FlashPlayerTrust
(e.g. /Library/Application Support/Macromedia/FlashPlayerTrust)
<app data>/Macromedia/Flash Player/#Security/FlashPlayerTrust
(e.g. /Users/fred/Library/Preferences/Macromedia/Flash Player/#Security/FlashPlayerTrust)
These locations are directories, not individual files. Any number of configuration files may be installed in each of these directories; Flash Player will read all files it finds in them. Configuration files may not be placed in subdirectories of FlashPlayerTrust; they must be placed directly in the FlashPlayerTrust directories. The individual configuration files may be given any name but, to avoid naming conflicts, installers should name their configuration files in some way that is specific to their product. The FlashPlayerTrust directories will not necessarily exist on any given system, so installers may need to create them.
The syntax of these files is simple: They contain any number of local paths, one per line. Whitespace and blank lines are allowed. Comments can be included with the # character; these comments go to the end of a line. Quotes are unnecessary (and will cause problems) for paths that contain spaces.
These files contain filesystem paths, which on some users' computers may include non-ASCII characters, so the text encoding used in FlashPlayerTrust files is significant. Flash Player will look for Unicode byte-order mark characters at the beginnings of these files, and will recognize UTF-8 and UTF-16 byte order marks, treating the rest of the file as UTF-8 or UTF-16 accordingly. (Windows Notepad and Mac TextEdit, for example, can write Unicode text files containing these byte-order mark characters; many other text editors can as well.) If Flash Player does not find a byte-order mark character at the beginning of a FlashPlayerTrust file, it will interpret the file using the current "codepage" (default local encoding) of the computer.
While we usually speak of SWFs being placed in sandboxes, Flash Player also places HTML files in sandboxes for purposes of controlling SWF-HTML interactions. Local HTML files only have two sandboxes: trusted and untrusted. Local HTML files are untrusted by default, and can be designated as trusted in the same way as SWFs. The sandbox of a local HTML file matters only for HTML-to-SWF scripting, such as with the Flash Player JavaScript API.
A SWF may determine its own sandbox type using the following read-only ActionScript property:
This property has one of the following four string values:
SWFs in the local-with-filesystem sandbox may perform local-read operations but not net-send or SWF-HTML operations.
If you are using a Debug version of Flash Player, and you are connected to the debugger in Flash, then whenever a SWF in this sandbox attempts a prohibited operation, you will see a diagnostic message in the Output panel describing the failed operation.
When a user is playing a SWF with a publish version of 7 or earlier in this sandbox, and the SWF attempts a prohibited operation, a security warning dialog box will appear, indicating that the content may have stopped working as intended due to the change in Flash Player 8's local security rules (see Figure 3).
This dialog box is shown at most once each time an application runs—subsequent operations will not trigger it but will fail silently instead.
The attempted operation will fail no matter what action the user takes in the dialog box. However, if the user clicks the Settings button, a new window will open displaying the Settings Manager, where the user may opt to trust the local content that attempted the prohibited operation. If the user chooses the Add Location command in the Settings Manager within a short time of seeing the Flash Player Settings Manager in Figure 2, a tip shows the path of the local SWF that attempted the prohibited operation (see Figure 4).
The user may opt simply to copy this path into the Trust This Location text box, thus trusting the individual SWF that triggered the dialog box. This is sometimes sufficient; however, sometimes an application will consist of multiple files, and it may be necessary to trust more than one file in order to get the application to work as intended. (See the section on cooperating media later.) Thus, the user may have to experiment with trusting multiple files or the entire directory containing the SWF that triggered the dialog box.
If the user makes changes in the Settings Manager, they must restart the original application (generally by refreshing their browser) before their changes take effect.
The documentation that surrounds the security panel of the Settings Manager explains the above workflow for end users. Users can also access the TechNote, How Do I Let Local Flash Content Communicate with the Internet?, for step-by-step instructions on trusting local content.
For end users, the local security warning dialog box appears only for SWFs of version 7 and earlier. The dialog box is intended to permit users to fix pre–Flash 8 content that has been affected by the new local security rules.
However, for authors of Flash content, the security warning dialog box may be a helpful indicator of why failures are occurring. Authors may wish to be informed immediately whenever a SWF of any version attempts an operation prohibited by the local security rules.
To support this need, a variety of our authoring tools, including Flash 8, install a file called FlashAuthor.cfg that instructs Flash Player to show the warning dialog box for a prohibited operation by any local-with-filesystem SWF, regardless of version. Any user is free to create this file themselves as well. The file can be placed in either of two locations, each alongside the FlashPlayerTrust directories:
<system>\Macromed\Flash\FlashAuthor.cfg
(e.g. c:\WINNT\system32\Macromed\Flash\FlashAuthor.cfg)
<app data>\Macromedia\Flash Player\#Security\FlashAuthor.cfg
(e.g. c:\Documents and Settings\fred\Application Data\Macromedia\Flash Player\#Security\FlashAuthor.cfg)
<app support>/Macromedia/FlashAuthor.cfg
(e.g. /Library/Application Support/Macromedia/FlashAuthor.cfg)
<app data>/Macromedia/Flash Player/#Security/FlashAuthor.cfg
(e.g. /Users/fred/Library/Preferences/Macromedia/Flash Player/#Security/FlashAuthor.cfg)
Only one directive is currently recognized in this file:
LocalSecurityPrompt=Author
This directive causes Flash Player to ignore SWF version when deciding whether to show the warning dialog box in Figure 3.
FlashAuthor.cfg may also contain whitespace, and comments denoted by the # character, running to the end of the line.
If you are developing SWF content that is designed to play as local files, the LocalSecurityPrompt=Author directive may be undesirable for you because it prevents Flash Player from simulating end-user behavior perfectly. You can disable the author-specific behavior by changing the contents of FlashAuthor.cfg to anything other than LocalSecurityPrompt=Author as shown above. For example, you can comment out the line above, or you can change it to something easy to understand, such as:
LocalSecurityPrompt=User
Note that Flash 8 installs FlashAuthor.cfg in both the all-users and single-user locations. When FlashAuthor.cfg is present in both locations, Flash Player honors the copy in the single-user location, so be sure to edit the single-user file.
SWFs in the local-with-networking sandbox may perform net-send operations but not local-read or SWF-HTML operations.
If you are using a Debug version of Flash Player, and you are connected to the debugger in Flash, then whenever a SWF in this sandbox attempts a prohibited operation, you will see a diagnostic message in the Output panel describing the failed operation.
SWFs in this sandbox will not cause the security warning dialog box to be displayed because there are no situations in which content could have been made before the local security rules were changed, and yet be in the local-with-networking sandbox. From an end-user perspective, all prohibited operations in this sandbox fail silently.
Local-with-networking SWFs may perform net-send operations. Some net-send operations are one-way operations, where data is sent but no reply comes back; other net-send operations are requests for which a response is received. These latter operations are called net-read operations, a superset of net-send operations. An example of a net-read operation is XML.load("http://mysite.com/data/schedule.xml"). Local-with-networking SWFs are permitted to attempt net-read operations. However, in keeping with Flash Player's global permission principle, in order for a local-with-networking SWF to load data from a given domain, that domain must serve a policy file that authorizes all domains to read the relevant data, stating <allow-access-from domain="*" />. In the above example, mysite.com would need a policy file at either the default location (http://mysite.com/crossdomain.xml) or next to the desired data (http://mysite.com/data/crossdomain.xml). In the latter case, the loading SWF would need to call the following in order to inform Flash Player of the non-default policy file location:
System.security.loadPolicyFile("http://mysite.com/data/crossdomain.xml")
Thus far, we have discussed local security from the point of view of a single SWF operating on its own: No individual SWF may have both local-read and net-send privileges without authorization from the user. But the local security enhancements in Flash Player 8 must also protect Flash Player users when multiple SWFs cooperate with each other. No cooperating set of SWFs can collectively have both local-read and net-send privileges.
Achieving cooperation between SWFs requires two steps. First, one SWF must load another, generally using the ActionScript loadMovie command. Second, the two SWFs must exchange information, using ActionScript variables, method calls, LocalConnection objects, or the like. This exchange of information is sometimes called cross-scripting.
To maintain local security, Flash Player prohibits SWF loading in some cases; in other cases, it permits SWF loading but limits cross-scripting.
SWF loading and cross-scripting are always permitted between SWFs that reside in the same sandbox. So, for example, any local-with-filesystem SWF may load and cross-script any other local-with-filesystem SWF; any local-with-networking SWF may load and cross-script any other local-with-networking SWF; and so on. The restrictions appear when two SWFs from different sandboxes attempt to cooperate.
Table 1 summarizes loading and cross-scripting restrictions between sandboxes; the individual rules appear after. In any cooperation between SWFs, there are two parties. We call the SWF that initiates the cooperation (calls loadMovie or performs cross-scripting) the accessing SWF, and the other SWF the accessed SWF. The labels at the top of the table represent the sandbox of the accessing SWF, and the labels at the left represent the sandbox of the accessed SWF.
| Sandbox of Accessed SWF | Local- with- filesystem |
Local- with- networking |
Local- trusted |
Remote |
|---|---|---|---|---|
| Sandbox of Accessing SWF | ||||
| Local- with- filesystem |
Load: allowed Cross-script: allowed |
Load: not allowed | Load: allowed Cross-script: allowed |
Load: not allowed |
| Local- with- networking |
Load: not allowed | Load: allowed Cross-script: allowed |
Load: allowed Cross-script: allowed |
Load: not allowed |
| Local- trusted |
Load: allowed Cross-script: requires permission |
Load: allowed Cross-script: requires permission |
Load: allowed Cross-script: allowed |
Load: not allowed |
| Remote | Load: not allowed | Load: allowed Cross-script: requires permission |
Load: allowed Cross-script: allowed |
Load: allowed Cross-script: requires permission if domains don't match |
The red cells in Table 1 indicate situations where certain SWFs cannot load others (using loadMovie, loadMovieNum, etc.):
The latter two rules can be worked around when necessary because it is easy to change a SWF from local-with-filesystem to local-with-networking or vice versa.
However, the first rule—that remote SWFs cannot load local SWFs—is absolute. It cannot be worked around, unlike most other security rules in Flash Player. This rule avoids what are called zone escalations, where content in a less privileged zone (a remote SWF) activates content from a potentially more privileged zone (local SWFs). If you find yourself in the unusual position of maintaining a hybrid remote-local application that starts locally installed content when users visit a web page, your best option is to change your entry point, asking users to start by viewing a local SWF (or local projector, local executable, etc) that then activates your online content.
Flash Player has similar rules for calling getURL, which loads browser pages rather than SWFs:
The yellow cells in Table 1 indicate situations where one SWF may script another, as long as the accessed SWF explicitly grants permission for the operation. These situations include the following:
In keeping with the Flash Player global permission principle, the first two of these situations require the accessed SWF to grant permission to accessing SWFs from all sandboxes. This means calling System.security.allowDomain("*") or, for LocalConnection objects, providing a LocalConnection.allowDomain handler that returns a true value when provided with a domain argument specifying "localhost."
Flash Player 6 and later support persistent shared objects through the SharedObject class. Persistent shared objects store data on users' computers. They are usually local shared objects, obtained with SharedObject.getLocal. It is also possible to create persistent remote shared objects; this requires Flash Media Server (formerly Flash Communication Server), and remote shared objects are documented with that product.
Each remote sandbox has an associated store of persistent shared objects. For example, when any SWF from domain1.com reads or writes a persistent shared object, Flash Player will read or write that object in the domain1.com object store. Likewise for a SWF from domain2.com, Flash Player will use the domain2.com store. To avoid name collisions, persistent shared objects are further identified by a path, which defaults to the full path in the URL of the creating SWF, but can be shortened using the localPath parameter to SharedObject.getLocal, which allows other SWFs from the same domain to access a shared object after it is created.
In Flash Player 7 and earlier, all local SWFs shared a single persistent shared object store. Starting with Flash Player 8, there are two local shared object stores. Repeating an earlier pattern, Flash Player ensures that local-with-filesystem SWFs cannot communicate with local-with-networking SWFs—in this case by assigning a separate shared object store to each of these two local sandboxes.
Flash Player assigns local-trusted SWFs to the same shared object store as local-with-filesystem SWFs. This helps ease transitions between local-with-filesystem status (the default) and local-trusted status (which end users may elect as a repair measure for existing local content that stops working as expected). When SWFs make this transition, they retain any shared objects they have created.
The following scenarios are meant to help illustrate the effects of the new local security rules in Flash Player 8.
The Flash Player 8 local security rules are designed to help protect end users. For end users, local SWFs are generally some form of final content—something that was downloaded from an Internet source or installed as part of an application. For Flash authors, however, local SWFs are frequently just a temporary copy of content in development—usually content that is bound for eventual deployment on an HTTP server. You may sometimes encounter security restrictions that prevent your content from working as you expect, simply because you are previewing your SWFs while they are still local files.
Consider the following three ways of testing Flash content in development, in order of increasing complexity:
Ideally, to avoid undesirable security restrictions during preview-in-browser testing, it would be helpful if Flash Player could distinguish Flash content under development from untrusted SWFs downloaded from Internet sources. Unfortunately, there is no reliable automated way for Flash Player to do this.
Instead, you may find it helpful to configure Flash Player to trust all SWFs in a certain region of your local filesystem. For example, if you store all of your Flash work under C:\FlashSites, you can visit the Settings Manager and add the directory C:\FlashSites to your list of trusted paths. Thereafter, whenever you view any SWFs within C:\FlashSites or any of its subdirectories, Flash Player will place those SWFs in the local-trusted sandbox, thus avoiding any security-related failures. Once you do this, be sure not to place SWFs into your trusted area from sources you do not trust! Keeping your own local SWFs separate from other authors' untrusted SWFs will allow you to benefit from the same increased protections that all Flash Player end users benefit from.
Let's imagine that you've visited the Settings Manager and configured a trusted directory. Now your own work proceeds uninterrupted by security problems. However, you may need to share your SWFs in development with a variety of colleagues—HTML authors, Flex developers, bitmap artists, and so on. Or you may wish to show your SWFs to managers or clients. Some of these people will probably not have set up trusted directories on their computers, so if they open your SWFs as local files and your SWFs attempt to communicate with the Internet (for example, by calling getURL), or with HTML pages, the local security rules may cause your content not to work as intended while it is being previewed locally. In addition, some of these "extended family" users probably will not have FlashAuthor.cfg installed on their computers, so if your SWFs are version 8 or higher, those people won't even see warning dialog boxes informing them of the reason for failure.
Unfortunately, there is no single recipe for handling these extended-family issues. The basic problem is that when Flash Player runs on your colleagues' computers, it has no way of distinguishing your (temporarily) local SWFs from potentially untrustworthy SWFs that came from Internet downloads.
The surest way to solve extended-family issues is to post your SWFs on an HTTP testing server and then send out links, rather than sending your SWFs around as files. However, this is sometimes inconvenient or impossible—for example, when you don't have a private HTTP server or when you need to share SWFs with people outside your own network and you don't want to post the SWFs on public servers. Thus, you may need to consider other possibilities:
The best solution for you will depend on your situation.
For the most part, the new local security rules should be invisible to Flash Player end users. However, as just described, it is possible that some users may have local Flash applications that were written to communicate with the Internet. When these users upgrade to Flash Player 8, they may begin seeing dialog boxes informing them of potentially insecure operations.
A user's options in this situation are simple. They may decide to ignore the problem, they may contact the application vendor to inquire about a fix, or they may elect to try and fix the problem themselves.
Users who decide to fix the problem may click the Settings button in the warning dialog box. This will take them to the Settings Manager, where they can read about local security, choose Edit Locations > Add Location, and select a local path to trust. It is not always trivial to figure out what path needs to be trusted; sometimes trusting just the single path that appeared in the warning dialog box is enough but sometimes multiple SWFs may be involved in an application. In such situations it will sometimes be necessary to trust the entire directory containing those SWFs. After each guess at a trusted path, the user will have to return to the original application and restart it—for example, by refreshing their browser.
Upon reaching the Settings Manager, users may also decide to select Always Allow to trust all SWFs of version 7 and earlier. This is a simpler fix than determining paths to trust but it reduces users' security in return for this convenience.
Let us imagine that you are maintaining an application that uses local SWFs and you receive inquiries from your users who say they are seeing Flash Player Security dialog boxes informing them of potentially insecure operations when they view certain parts of your application. Let's say your application is a hybrid help system, which is a common form of local SWF application: a collection of HTML and SWF files that communicate with each other using getURL and possibly fscommand.
A first step should be to determine how serious the problem is. Is this a crucial component of an important application with a major break, or has a small feature broken in a hobby project? Are you willing to redistribute fixed files to all your users? The answer will often be yes, but be sure to validate the need for a fix before investing in one.
One option is to simply tell users to visit the Settings Manager and trust the path where your help system resides. However, this may involve too many steps for some users to complete, and may also make users uncomfortable if they do not understand the implications of their security decisions.
Another option is to republish your SWFs as local-with-networking, or postprocess them using the Local Content Updater. If the only security violations that your content produces are from calls to getURL, this should be sufficient. However, if your SWF and HTML files script each other using fscommand, getURL("javascript:..."), or other hybrid scripting operations, the local-with-networking sandbox is not enough to restore your application to its former state; you must place your SWFs in the local-trusted sandbox.
If your users are technically savvy, you can provide them with a FlashPlayerTrust file and instructions on where to place it. Alternatively, you can create a small script or program that automatically creates a FlashPlayerTrust file in the appropriate location. If you know where your SWFs are installed, you can simply trust the directory where you expect them to reside. However, if users have chosen a non-default install location, you may need to prompt users for the location where they have installed your content, or search their filesystems for your SWFs.
For our final scenario, let's imagine you are building a local SWF application that is intended to periodically synchronize data with an HTTP server and serve as a local repository of that data at other times. The data in question might be an address book, so think of this application as an "occasionally connected contact manager."
Let's say you've determined that you need net-send privileges, but not local-read privileges—for example, you won't need to read local XML files for configuration. So, when publishing your SWF(s), you select Access Network Only under Local Playback Security in the Flash publish options. Now your SWFs are free to use getURL, XML.load, and other HTTP operations.
Now you set about connecting your application to the HTTP data source for synchronization. Let's say you're using XML.sendAndLoad() to exchange simple XML data. Because XML.sendAndLoad is a net-read operation, you need a policy file on the HTTP server that you're synchronizing with. Let's say you want your policy file to govern only the relevant data, not the whole HTTP server—so you put the policy file next to the XML data source and you call System.security.loadPolicyFile in your client SWF, specifying the location of the policy file. The policy file looks like this:
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>
The policy file must trust all locations ("*") so that your local-with-networking SWF(s) can load data from your server, in keeping with the global permission principle.
That should do it!
The following diagrams summarize the explanation of local security privileges described in previous sections.
All SWFs are placed in a sandbox when they are loaded into the Flash Player. Figure 5 shows how SWFs are assigned to sandboxes based on their origin. SWFs from the network, for example from a.com and b.com, are always placed in a sandbox that corresponds to their origin domain.
SWFs from local origins (local filesystems or UNC network paths) are placed into one of three sandboxes. By default, a local SWF is placed in the local-with-filesystem sandbox. Local files that have declared that they wish to have network access are placed in the local-with-networking sandbox. Local files that are registered as trusted (via the Settings Manager or configuration files) are placed in the local-trusted sandbox. (In Flash Player 7 and earlier, all local files are placed in the local-trusted sandbox.)
Any two SWFs in the same sandbox may interact freely with each other. Later diagrams explain how SWFs may interact with SWFs from other sandboxes, and with filesystems and servers.
In Figure 5, arrows represented SWF origin. In the following series of diagrams, arrows illustrate access instead. Dashed arrows represent data loading and outlined arrows represent cross-scripting. Figure 6 illustrates the privileges available to SWFs that fall into default sandboxes.
By default, local SWFs are placed in the local-with-filesystem sandbox. From this sandbox, SWFs may read (using XML.load(), for example) from files on local filesystems or UNC network paths but they may not communicate with the Internet in any way.
The privileges for remote SWFs are no different from Flash Player 7, with the exception that remote SWFs may no longer load local content. Remote SWFs are always placed in a sandbox corresponding to their origin domain. From the a.com sandbox, a SWF may read (using XML.load(), for example) from the server at a.com and may send data (using XML.send(), for example) anywhere on the Internet.
Figure 7 illustrates privileges for remote SWFs that are not available by default but may be granted using permissions.
A SWF from a.com may read (using XML.load, for example) from the server at b.com if b.com has a policy file that permits access from a.com, or from all domains. A SWF from a.com may cross-script a SWF from b.com (calling an ActionScript method in the b.com SWF, for example) if the b.com SWF calls System.security.allowDomain("a.com"). These permissions are available in Flash Player 7 and have not changed in Flash Player 8.
By default, remote SWFs may not cross-script local SWFs. However, local-with-networking SWFs and local-trusted SWFs are allowed to grant permissions for cross-scripting by remote SWFs, using System.security.allowDomain(). Local-with-filesystem SWFs are not allowed to grant such permissions because this would make it possible for a local-with-filesystem SWF and a remote SWF to cooperate in reading data from a local filesystem and sending the data to a web server.
Figure 8 shows the unrestricted privileges given to local-trusted SWFs. Local-trusted SWFs may read from local files, interact with any server, and script any other SWF.
Figure 9 illustrates privileges for local-with-filesystem SWFs that are not available by default, but may be granted using permissions. Local-trusted SWFs may grant permission, using System.security.allowDomain("*"), to be scripted by local-with-filesystem SWFs.
Note that permissions can only be granted to local-with-filesystem SWFs by granting permissions to all domains. The all-domains requirement reflects the fact that allowing access by local-with-filesystem SWFs is equivalent to allowing access by anyone because Flash Player cannot determine the origin of a local SWF.
Permissions cannot be granted to local-with-filesystem SWFs by remote SWFs or local-with-networking SWFs because this would make it possible for a local-with-filesystem SWF and a remote or local-with-networking SWF to cooperate in reading data from a local filesystem and sending the data to a web server.
In the absence of permissions, local-with-filesystem SWFs are allowed only to load data from local filesystems (using XML.load(), for example).
Figure 10 shows the default privileges available to local SWFs that have declared themselves local-with-networking rather than local-with-filesystem. In the absence of permissions, local-with-networking SWFs are only allowed to communicate with other local-with-networking SWFs and send data to servers (using XML.send(), for example).
Figure 11 illustrates privileges for local-with-networking SWFs that are not available by default, but may be granted using permissions.
A local-with-networking SWF is allowed to read (using XML.load(), for example) from the server at a.com if a.com has a policy file that permits access from all domains.
A local-with-networking SWF is allowed to cross-script a SWF from a.com (calling an ActionScript method in the a.com SWF, for example) if the a.com SWF calls System.security.allowDomain("*"). Similarly, a local-with-networking SWF will be allowed to cross-script a local-trusted SWF if the local-trusted SWF calls allowDomain("*").
Note that permissions can only be granted to local-with-networking SWFs by granting permissions to all domains. The all-domains requirement reflects the fact that allowing access by local-with-networking SWFs is equivalent to allowing access by anyone because Flash Player cannot determine the origin of a local SWF.
No permissions can ever be established to allow local-with-networking SWFs to read from local files.
Figure 12 summarizes the data flows that are possible with a maximal set of permissions in place.
By using permissions, local-with-networking SWFs can be made completely interoperable with remote SWFs and servers. Permissions also make it possible for local-trusted SWFs to communicate freely with network resources and vice versa.
Note, however, that even with this maximal set of permissions, data cannot flow from local filesystems to the Internet without going through a local-trusted SWF.
It is possible to build local applications that embed Flash Player, including it as a component in a custom GUI. This applies only to native local applications, built as exectuable programs.
We currently do not provide support for this type of usage of Flash Player but we do not forbid it either. Using Flash Player in your application is risky because you cannot redistribute Flash Player with your application, which forces you to depend on whatever version of Flash Player is installed on your users' computers. Since users may upgrade Flash Player at any time, this leaves your application vulnerable to unanticipated changes in behavior.
Despite these problems, we make an effort to avoid causing undue pain for applications that embed Flash Player.
Flash Player 8 and higher have the following local security behavior in embedding situations:
ActiveX (IDispatch APIs):
HRESULT IShockWaveFlash::EnforceLocalSecurity()
HRESULT IShockWaveFlash::DisableLocalSecurity()
Plugins (DLL exports):
NPError Flash_EnforceLocalSecurity()
NPError Flash_DisableLocalSecurity()
If you are developing a local application that embeds Flash Player, you should make an explicit decision as to whether you want the local security rules enabled or disabled and call the appropriate API. In general, if your usage of Flash Player includes playing SWF content from sources you do not control, such as from the Internet, you should elect to enable local security rules. On the other hand, if you are playing only specific SWFs that you control and ship with your application, you may find it convenient to disable local security for maximum flexibility.
Users of Flash Player 8 and later have an option that's similar to what many browsers provide for third-party cookies: Users may disable the reading and writing of client-persistent shared objects by SWFs from third-party domains. By default, third-party storage is enabled; users may disable it by visiting the Flash Player Settings Manager and unchecking Allow Third-Party Flash Content to Store Data on Your Computer. A third-party SWF is any SWF whose domain of origin does not match the primary domain the user is visiting—the domain shown in the browser's address bar.
The third-party storage option affects both local shared objects and their lesser-known cousins, persistent remote shared objects, which are used only in conjunction with Flash Media Server (formerly Flash Communication Server).
When third-party storage is disabled, and a SWF attempts to obtain a shared object using SharedObject.getLocal() or SharedObject.getRemote(), Flash Player determines whether the calling SWF is a third party or not. Flash Player compares the SWF's origin domain to the domain shown in the browser's address bar and classifies the SWF as a third party if the two domains do not match exactly. If the SWF is a third party, the call to getLocal() or getRemote() returns null.
The third-party storage restriction does not affect local SWFs (those loaded from users' filesystems); it affects remote SWFs only. Because the classification of third-party SWFs requires comparison to a browser URL, Flash Player observes the third-party restriction only when playing within the web browser; stand-alone players, projectors, and the Flash authoring players do not.
If your SWF is genuinely a third party—that is, it is being incorporated into someone else's site—you must accept that certain users will not permit your SWF to read or write shared objects. See the next section for a discussion of why this is so.
If your SWF is being treated as a third party, but is used only within sites that are under your control, you may need to reorganize your site so that any SWFs that need to read or write persistent shared objects are always served from the primary domain that the user is visiting.
Surfing the Web represents a tradeoff between privacy and convenience. Users generally cannot avoid revealing certain facts about themselves, such as their IP addresses and their choices of operating system and browser, but generally wish to keep most information about themselves private unless they deliberately provide that information to known, trusted parties. One aspect of users' personal profiles that has been called into debate in recent years is browsing history, as revealed by tracking information stored by web content. If many different sites make a record of a particular user's visit in a similar way, and the same or other sites are later able to read all of that information to build a picture of a user's browsing habits, some users (and public advocates of user privacy) feel that their privacy has been violated.
There are generally two places such tracking records can be stored: on web servers and on a user's own computer. Client technologies like web browsers and Flash Player can't influence what happens on web servers, so this option remains available to parties who wish to learn users' browsing history. However, storing browsing records on servers has some key disadvantages: storage space and server-to-server communication are needed, and both can be expensive. In addition, it is often difficult to identify a user across multiple visits, because identifying traits like IP addresses may vary with time, or may be shared by many users. Thus, history trackers prefer, if possible, to store records of browsing history on users' own computers, building up a record of sites visited using a given computer.
Two technologies used to store such information are browser cookies and persistent shared objects in Flash. Browsers and Flash Player implement a same-origin security policy, which prevents sites from reading cookies or shared objects established by other sites. Because of this restriction, it is insufficient for each participating site to store a browsing record in its own data store; no other sites would be able to read this information to build up an aggregate history. Instead, a commonly used technique is to designate some single domain to record all the history information and then have each participating site reference a history-writing document from that domain, passing site-identifying information in the URL used to retrieve the document. On later visits, a history-reading document from the common domain can access all records written by the cookie-writing document, thus revealing part of the user's browsing history.
Web browsers and Flash Player now give users control over how their history may be tracked with this technique. Browsers and Flash Player provide users with the option to disable the reading and writing of "third-party" persistent data. A third party, in this sense, is defined as any domain that does not match the primary domain the user is visiting—the domain shown in the browser's address bar. For example, if a user has disabled third-party storage and then visits http://site1.com/index.html, and index.html includes http://common.com/writeHistory.html?domain=site1.com, and writeHistory.html attempts to read or write persistent data, the browser or Flash Player will not permit the operation because common.com is a third-party domain; the user is looking at site1.com in their browser, not common.com.
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:
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:
<object
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">
<param name="movie" value="hello.swf">
<param name="allowScriptAccess" value="sameDomain">
<embed
pluginspage="http://www.macromedia.com/go/getflashplayer"
type="application/x-shockwave-flash"
src="hello.swf"
width="375" height="300"
allowScriptAccess="sameDomain">
</object>
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.
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. We do 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.
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. We do 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.
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.
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.
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.
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. We do 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.
To remain up to date about Flash security, please read the latest security documents in the Flash Player Developer Center.
| 04/23/2012 | Auto-Save and Auto-Recovery |
|---|---|
| 04/23/2012 | Open hyperlinks in new window/tab/pop-up ? |
| 04/21/2012 | PNG transparencies glitched |
| 04/01/2010 | Workaround for JSFL shape selection bug? |
| 02/13/2012 | Randomize an array |
|---|---|
| 02/11/2012 | How to create a Facebook fan page with Flash |
| 02/08/2012 | Digital Clock |
| 01/18/2012 | Recording webcam video & audio in a flv file on local drive |