Security

Introduction to security

Adobe® Flash® Player runs applications built as SWF files. Content is delivered as a series of instructions in binary format to Flash Player over web protocols in the precisely described SWF (.swf) file format. The SWF files themselves are typically hosted on a server and then downloaded to, and displayed on, the client computer when requested. Most of the content consists of binary ActionScript instructions. ActionScript is the ECMA standards-based scripting language that Flash uses that features APIs designed to allow the creation and manipulation of client-side user interface elements and for working with data.

The Flex security model protects both client and the server. Consider the following two general aspects to security:

  • Authorization and authentication of users accessing a server's resources

  • Flash Player operating in a sandbox on the client

Flex supports working with the web application security of any J2EE application server. In addition, precompiled applications can integrate with the authentication and authorization scheme of any underlying server technology to prevent users from accessing your applications. The Flex framework also includes several built-in security mechanisms that let you control access to web services, HTTP services, and server-based resources such as EJBs.

Flash Player runs inside a security sandbox that prevents the client from being hijacked by malicious application code.

Note: SWF content running in the Adobe® AIR™ follows different security rules than content running in the browser. For details, see Adobe AIR Security.

Declarative compared to programmatic security

The two common approaches to security are declarative and programmatic. Often, declarative security is server based. Using the server's configuration, you provide protection to a resource or set of resources. You use the container's authentication and authorization schemes to protect that resource from unauthorized access.

The declarative approach to security casts a wide net. Declarative security is implemented as a separate layer from the web components that it works with. You set up a security system, such as a set of file permissions or users, groups, and roles, and then you plug your application's authentication mechanism into that layer.

With declarative security, either a user gains access to the resource or they do not. Usually the content cannot be customized based on roles. In an HTML-based application, the result is that users are denied access to certain pages. However, in a Flex environment, the typical result of declarative security is that the user is denied access to the entire application, since the application is seen as a single resource to the container.

Declarative security lets programmers who write web applications ignore the environment in which they write. Declarative security is typically set up and maintained by the deployer and not the developer of the application. Also, updates to the web application do not generally require a refactoring of the security model.

Programmatic security gives the developer of the application more control over access to the application and its resources. Programmatic security can be much more detailed than declarative security. For example, a developer using programmatic security can allow or deny a user access to a particular component inside the application.

Although programmatic security is typically configured by the developer of the application, it usually interacts with the same systems as declarative security, so the relationship between developer and deployer of the application must be cooperative when implementing programmatic security.

Declarative security is recommended over programmatic security for most applications because the design promotes code reuse, making it more maintainable. Furthermore, declarative security puts the responsibility of security into the hands of the people who specialize in its implementation; application programmers can concentrate on writing applications and people who deploy the applications in a specific environment can concentrate on enforcing security policies and take advantage of that context.

Client security overview

When considering security issues, you cannot think of applications as traditional web applications. Applications built with Flex often consist of a single monolithic SWF file that is loaded by the client once, or a series of SWF files loaded as modules or RSLs. Web applications, on the other hand, usually consist of many individual pages that are loaded one at a time.

Most web applications access resources such as web services that are outside of the client. When an application accesses an external resource, two factors apply:

  • Is the user authorized to access this resource?

  • Can the client load the resource, or is it prevented from loading the resource, because of its sandbox limitations?

The following basic security rules always apply by default:

  • Resources in the same security sandbox can always access each other.

  • SWF files in a remote sandbox can never access local files and data.

You should consider the following security issues related to the client architecture that affect applications.

Flash Player security features

Much of Flash Player security is based on the domain of origin for loaded SWF files, media, and other assets. A SWF file from a specific Internet domain, such as www.example.com, can always access all data from that domain. These assets are put in the same security grouping, known as a security sandbox. For example, a SWF file can load SWF files, bitmaps, audio, text files, and any other asset from its own domain. Also, cross-scripting between two SWF files from the same domain is permitted, as long as both files are written using ActionScript 3.0. Cross-scripting is the ability of one SWF file to use ActionScript to access the properties, methods, and objects in another SWF file. Cross-scripting is not supported between SWF files written using ActionScript 3.0 and files using previous versions of ActionScript; however, these files can communicate by using the LocalConnection class.

Memory usage and disk storage protections

Flash Player includes security protections for disk data and memory usage on the client computer.

The only type of persistent storage is through the SharedObject class, which is embodied as a file in a directory whose name is related to that of the owning SWF file. An application cannot typically write, modify, or delete any files on the client computer other than SharedObject data files, and it can only access SharedObject data files under the established settings per domain.

Flash Player helps limit potential denial-of-service attacks involving disk space (and system memory) through its monitoring of the usage of SharedObject classes. Disk space is conserved through limits automatically set by Flash Player (the default is 100K of disk space for each domain). The author can set the application to prompt the user for more disk space, or Flash Player automatically prompts the user if an attempt is made to store data that exceeds the limit. In either case, the disk space limit is enforced by Flash Player until the user gives explicit permission for an increased allotment for that domain.

Flash Player contains memory and processor safeguards that help prevent applications from taking control of excess system resources for an indefinite period of time. For example, Flash Player can detect an application that is in an infinite loop and select it for termination by prompting the user. The resources that the application uses are immediately released when the application closes.

Flash Player uses a garbage collector engine. The processing of new allocation requests always first ensures that memory is cleared so that the new usage always obtains only clean memory and cannot view any previous data.

Privacy

Privacy is an important aspect of overall security and your application should provide very little information that would reveal anything about a user (or their computer). Flash Player does not provide personal information about users (such as names, e-mail addresses, and phone numbers), or provide access to other sensitive information (such as credit card numbers or account information).

What Flash Player does provide is basically standardized hardware and software configuration information that authors might use to enhance the user experiences in the environment encountered. The same information is often available already from the operating system or web browser.

Information about the client environment that is available to the application includes:

  • User agent string, which typically identifies the embedding browser type and operating system of the client

  • System capabilities such as the language or the presence of an MP3 decoder (see the Capabilities class)

  • Presence of a camera and microphone

  • Keyboard and mouse input

ActionScript also includes the ability to replace the contents of the client's Clipboard by using the setClipboard() method of the System class. This method does not have a corresponding getClipboard() method, so protected data that might be stored in the Clipboard already is not accessible to Flash Player.

About sandboxes

The sandbox type indicates the type of security zone in which the SWF file is operating. In Flash Player, all SWF files (and HTML files, for the purposes of SWF-to-HTML scripting) are placed into one of four types of sandbox:

remote

All files from non-local URLs are placed in a remote sandbox. There are many such sandboxes, one for each Internet (or intranet) domain from which files are loaded.

local-with-filesystem

The default sandbox for local files. SWF files in this sandbox may not contact the Internet (or any servers) in any way—they may not access network endpoints with addresses such as HTTP URLs.

local-with-networking

SWF file in this sandbox may communicate over the network but may not read from local file systems.

local-trusted

This sandbox is not restricted. Any local file can be placed in this sandbox if given authorization by the end user. This authorization can come in two forms: interactively through the Settings Manager or noninteractively through an executable installer that creates Flash Player configuration files on the user's computer.

You can determine the current sandbox type by using the sandboxType property of the Security class, as the following example shows:

<?xml version="1.0" encoding="utf-8"?> 
<!-- security/DetectCurrentSandbox.mxml --> 
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark" 
    creationComplete="initApp()"> 
    
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
    
    <fx:Script><![CDATA[ 
        [Bindable] 
        private var mySandboxType:String; 
 
        private function initApp():void { 
            mySandboxType = String(Security.sandboxType); 
        } 
    ]]></fx:Script> 
 
    <s:HGroup> 
        <s:Label text="Sandbox Type: "/>                
        <s:Label id="tb1" text="{mySandboxType}"/>              
    </s:HGroup> 
</s:Application>

When you compile an application, you have some control over which sandbox the application is in. This determination is a combination of the value of the use-network compiler option (the default is true) and whether the SWF file was loaded by the client over a network connection or as a local file.

The following table shows how the sandbox type is determined:

use-network

Loaded

Sandbox type

false

locally

local-with-filesystem

true

locally

local-with-network

true

network

remote

false

network

n/a (causes an error)

Browser security

Flash Player clients can be one of the following four types:

  • Embedded Flash Player

  • Debugger version of embedded Flash Player

  • Stand-alone Flash Player

  • Debugger version of stand-alone Flash Player

The stand-alone Flash Player runs on the desktop. It is typically used by people who are running applications that are installed and maintained by an IT department that has access to the desktop on which the application runs.

The embedded Flash Player is run within a browser. Anyone with Internet access can run applications from anywhere with this player. For Internet Explorer, the embedded player is loaded as an ActiveX control inside the browser. For Netscape-based browsers (including Firefox), it is loaded as a plug-in inside the browser. Using an embedded player lets the developer use browser-based technologies such as FORM and BASIC authentication as well as SSL.

Browser APIs

Applications hosting the Flash Player ActiveX control or Flash Player plug-in can use the EnforceLocalSecurity and DisableLocalSecurity API calls to control security settings. If DisableLocalSecurity is opened, the application does not benefit from the local-with-networking and local-with-file-system sandboxes. All files loaded from the local file system are placed into the local-trusted sandbox. The default behavior for an ActiveX control hosted in a client application is DisableLocalSecurity.

If EnforceLocalSecurity is opened, the application can use all three local sandboxes. The default behavior for the browser plug-in is EnforceLocalSecurity.

Cross-scripting

Cross-scripting is when a SWF file communicates directly with another SWF file. This communication includes calling methods and setting properties of the other SWF file.

SWF file loading and cross-scripting are always permitted between SWF files that reside in the same sandbox. For example, any local-with-filesystem SWF file can load and cross-script any other local-with-filesystem SWF file; any local-with-networking SWF file can load and cross-script any other local-with-networking SWF file; and so on. The restrictions appear when two SWF files from different sandboxes or two remote SWF files with different domains attempt to cooperate.

For SWF files in the remote sandbox, if two SWF files were loaded from the same domain, they can cross-script without any restrictions. If both SWF files were loaded from a network, but from different domains, you must provide permissions to allow them to cross-script.

To enable cross-scripting between SWF files, use the Security class's allowDomain() and allowInsecureDomain() methods.

You call these methods from the called SWF file and specify the calling SWF file's domain. For example, if SWF1 in domainA.com calls a method in SWF2 in domainB, SWF2 must call the allowDomain() method and specifically allow SWF files from domainA.com to cross-script the method, as the following example shows:

 import flash.system.Security; 
 Security.allowDomain("domainA.com");

If the SWF files are in different sandboxes (for example, if one SWF file was loaded from the local file system and the other from a network) they must adhere to the following set of rules:

  • Remote SWF files (those served over HTTP and other non-local protocols) can never load local SWF files.

  • Local-with-networking SWF files can never load local-with-filesystem SWF files, or vice versa.

  • Local-with-filesystem SWF files can never load remote SWF files.

  • Local-trusted SWF files can load SWF files from any sandbox.

To facilitate SWF-to-SWF communication, you can also use the LocalConnection class. For more information, see Using the LocalConnection class.

ExternalInterface

You use the ExternalInterface API to let your application call scripts in the wrapper and to allow the wrapper to call functions in your application. The ExternalInterface API consists primarily of the call() and addCallback() methods in the flash.net package.

This communication relies on the domain-based security restrictions that the allowScriptAccess and allowNetworking properties define. You set the values of the allowScriptAccess and allowNetworking properties in the SWF file's wrapper. For more information, see About the object and embed tags.

By default, the application and the HTML page it is calling must be in the same domain for the call() method to succeed. For more information, see Communicating with the wrapper.

The navigateToURL() method

The navigateToURL() method opens or replaces a window in the Flash Player's container application. You typically use it to launch a new browser window, although you can also embed script in the method's call to perform other actions.

This usage of the navigateToURL() method relies on the domain-based security restrictions that the allowScriptAccess and allowNetworking parameters define. You set the values of the allowScriptAccess and allowNetworking parameters in the SWF file's wrapper. For more information, see About the object and embed tags.

Caching

Applications reside entirely on the client. If the browser loads the application, the application SWF file, plus externally loaded images and other media files, are stored locally on the client in the browser's cache. These files reside in the cache until cleared.

Storing a SWF file in the browser's cache can potentially expose the file to people who would not otherwise be able to see it. The following table shows some example locations of the browser's cache files:

Browser or operating system

Cache location

Internet Explorer on Windows XP

C:\Documents and Settings\username\Local Settings\Temporary Internet Files

Firefox on Windows XP

C:\Documents and Settings\username\Application Data\Mozilla\Firefox\Profiles\username.default\Cache

UNIX

$HOME/.mozilla/firefox/username.default/Cache/

These files can remain in the cache even after the browser is closed.

To prevent client browsers from caching the SWF file, try setting the following HTTP headers in the SWF file's wrapper:

 Cache-control: no-cache, no-store, must-revalidate, max-age=-1 
 Pragma: no-cache, no-store 
 Expires: -1

Note that in some cases, setting the Pragma header to "no-cache" can cause a runtime error with GET requests over SSL with the HTTPService class. In this case, setting just the Cache-control header should work.

Trusted sites and directories

The browser security model includes levels of trust applied to specific websites. Flash Player interacts with this model by assigning a sandbox based on whether the browser declared the site of the SWF file's origin trusted.

If Flash Player loads a SWF file from a trusted website, the SWF file is put in the local-trusted sandbox. The SWF file can read from local data sources and communicate with the Internet.

You can also assign a SWF file to be in the local-trusted sandbox when you load it from the local file system. To do this, you configure a directory as trusted by Flash Player (which results in the SWF file being put in the local-trusted sandbox) by adding a FlashPlayerTrust configuration file that specifies the directory to trust. This requires administrator access privileges to the client system, so it is typically used in controlled environments. Users can also define a directory as trusted by using the Flash Player User Settings Manager. For more information, see the Flash Player documentation.

Deploying secure applications

When you deploy an application, you make the application accessible to your users. The process of deploying an application is dependent on your application, your application requirements, and your deployment environment. You can employ some of the following strategies to ensure that the application you deploy is secure.

Deploying local SWF files versus network SWF files

Client computers can obtain individual SWF files from a number of sources, such as from an external website or a local file system. When SWF files are loaded into Flash Player, they are individually assigned to security sandboxes based on their origin.

Flash Player classifies SWF files downloaded from the network (such as from external websites) in separate sandboxes that correspond to their website origin domains. By default, these files are authorized to access additional network resources that come from the specific (exact domain name match) site. Network SWF files can be allowed to access additional data from other domains by explicit website and author permissions.

A local SWF file describes any file referenced by using the "file" protocol or a UNC path, which does not include an IP address or a qualifying domain. For example, "\\test\test.swf" and "file:\test.swf" are considered local files, while "\\test.com\test.swf" and "\192.168.0.1\test.swf" are not considered local files.

Local SWF files from local origins, such as local file systems or UNC network paths, are placed into one of three sandboxes: local-with-networking, local-with-filesystem, and local-trusted.

When you compile the application, if you set the use-network compiler option to false, local SWF files are placed in the local-with-filesystem sandbox. If you set the use-network compiler option to true, local SWF files are placed in the local-with-networking sandbox.

Local SWF files that are registered as trusted (by users or by installer programs) are placed in the local-trusted sandbox. Users can also reassign (move) a local SWF file to or from the local-trusted sandbox based on their security considerations.

Deploy checklist

Before you deploy your application, ensure that your proxy servers, firewalls, and assets are configured properly. For more information, see Deployment checklist.

Remove wildcards

If your application relies on assets loaded from another domain, and that domain has a crossdomain.xml file on it, remove wildcards from that file if possible. For example, change the following:

 <cross-domain-policy> 
 	<site-control permitted-cross-domain-policies="all"/> 
 	<allow-access-from domain="*" to-ports="*"/> 
 </cross-domain-policy>

to this:

 <cross-domain-policy> 
 	<site-control permitted-cross-domain-policies="by-content-type"/> 
 	<allow-access-from domain="*.myserver.com" to-ports="80,443,8100,8080" /> 
 </cross-domain-policy>

Also, set the value of the to-ports attribute of the allow-access-from tag to ensure that you are only allowing necessary ports access to the resources.

Check your application for calls to the allowDomain() and allowInsecureDomain() methods. During development, you might pass these methods a wildcard character (*), but now restrict those methods to allowing requests only from the necessary domains.

Deploy assets to WEB-INF

In some deployments, you want to make assets such as data files accessible to the application, but not accessible to anyone requesting the file. If you are using a J2EE-based server, you can deploy those files to a subdirectory within the WEB-INF directory. Based on J2EE security constraints, no J2EE server can return a resource from the WEB-INF directory to any client request. The only way to access files in this directory is with server-side code.

Loading assets

The most common task that developers perform that requires an understanding of security is loading external assets.

Data compared to content

The Flash Player security model makes a distinction between loading content and accessing or loading data. Content is defined as media: visual media that Flash Player can display, such as audio, video, or a SWF file that includes displayed media. Data is defined as something that you can manipulate only with ActionScript code.

You can load data in one of two ways: by extracting data from loaded media content, or by directly loading data from an external file (such as an XML file) or socket connection. You can extract data from loaded media by using the BitmapData.draw() method, the Sound.id3 property, or the SoundMixer.computeSpectrum() method. You can load data by using classes such as the SWFLoader, URLStream, URLLoader, Socket, and XMLSocket classes.

The Flash Player security model defines different rules for loading content and accessing data. Loading content has fewer restrictions than accessing data. In general, content such as SWF files, bitmaps, MP3 files, and videos can be loaded from anywhere, but if the content is from a domain other than that of the loading SWF file, it will be partitioned in a separate security sandbox.

When you load sub applications into a main application with the SWFLoader control, the sandbox into which you load it determines the level of interoperability between the applications. For more information, see About security domains.

Loading remote assets

Loading remote or network assets relies on three factors:

  • Type of asset. If the target asset is a content asset, such as an image file, you do not need any specific permissions from the target domain to load its assets into your application. If the target asset is a data asset, such as an XML file, you must have the target domain's permission to access this asset. For more information on the types of assets, see Data compared to content.

  • Target domain. If you are loading data assets from a different web domain, the target domain must provide a crossdomain.xml policy file. This file contains a list of URLs and URL patterns that it allows access from. The calling domain must match one of the URLs or URL patterns in that list. If the target asset is a SWF file, you can also provide permissions by calling the loadPolicyFile() method and loading an alternative policy file inside that target SWF file. For more information, see Using cross-domain policy files.

  • Loading SWF file's sandbox. To load an asset from a network address, you must ensure that your SWF file is in either the remote or local-with-networking sandbox. To ensure that a SWF file can load assets over the network, you must set the use-network compiler option to true when you compile the application. This is the default. If the application was loaded from the local file system with use-network set to false, the application is put in the local-with-filesystem sandbox and it cannot load remote SWF files.

Loading assets from a remote location that you do not control can potentially expose your users to risks. For example, the remote website B contains a SWF file that is loaded by your website A. This SWF file normally displays an advertisement. However, if website B is compromised and its SWF file is replaced with one that asks for a username and password, some users might disclose their login information. To prevent data submission, the loader has a property called allowNetworking with a default value of never.

Using cross-domain policy files

To make data available to SWF files in different domains, use a cross-domain policy file. A cross-domain policy file is an XML file that provides a way for the server to indicate that its data and documents are available to SWF files served from other domains. Any SWF file that is served from a domain that the server's policy file specifies is permitted to access data or assets from that server.

When a Flash document attempts to access data from another domain, Flash Player attempts to load a policy file from that domain. If the domain of the Flash document that is attempting to access the data is included in the policy file, the data is automatically accessible.

The default policy file is named crossdomain.xml and resides at the root directory of the server that is serving the data. The following example policy file permits access to Flash documents that originate from foo.com, friendOfFoo.com, *.foo.com, and 105.216.0.40:

 <?xml version="1.0"?> 
 <!-- http://www.foo.com/crossdomain.xml --> 
 <cross-domain-policy> 
 	<site-control permitted-cross-domain-policies="by-content-type"/> 
 	<allow-access-from domain="www.friendOfFoo.com"/> 
 	<allow-access-from domain="*.foo.com"/> 
 	<allow-access-from domain="105.216.0.40"/> 
 </cross-domain-policy>

You can also configure ports in the crossdomain.xml file.

You can use the loadPolicyFile() method to access a nondefault policy file.

Loading local assets

In some cases, your SWF file might load assets that reside on the client's local file system. This typically happens when the application is embedded on the client device and loaded from a network. If the application is allowed to access local assets, it cannot access network assets.

To ensure that an application can access assets in the local sandbox, the application must be in the local-with-filesystem or local-trusted sandbox. To ensure this, you set the use-network compiler option to false when you compile the application. The default value of this option is true.

When you load another SWF file that is in the local file system into your application with a class such as SWFLoader, and you want to call methods or access properties of that SWF file, you do not need to explicitly enable cross-scripting.

If the SWF files are in different sandboxes (for example, you loaded the main SWF file into the local-with-network sandbox, but loaded the asset SWF file from the network), you cannot cross-script because they are in different sandboxes. Remote SWF files cannot load local SWF files, and vice versa.

Using J2EE authentication

Applications built with Flex integrates well with any server environment, including J2EE. To effectively implement secure web applications in a J2EE environment, you should understand the following concepts:

Authentication

The process of gathering user credentials (user name and password) and validating them in the system. This requires checking the credentials against a user repository such as a database, flat file, or LDAP implementation, and authenticating that the user is who they say they are.

Authorization

The process of making sure that the authenticated user is allowed to view or access a given resource. If a user is not authorized to view a resource, the container does not allow access.

Using container-based authentication

J2EE uses the Java Authentication and Authorization Service (JAAS), Java security manager, and policy files to enforce access controls on users and ties this enforcement to web server roles. The authenticating mechanism is role based. That is, all users who access a web application are assigned to one or more roles. Example roles are manager, developer, and customer.

Application developers can assign usage roles to a web application, or to individual resources that make up the application. Before a user is granted access to a web application resource, the container ensures that the user is identified (logged in) and that the user is assigned to a role that has access to the resource. Any unauthorized access of a web application results in an HTTP 401 (Unauthorized) status code.

Authentication requires a website to store information about users. This information includes the role or roles assigned to each user. In addition, websites that authenticate user access typically implement a login mechanism that forces verification of each user's identity by using a password. After the website validates the user, the website can then determine the user's roles.

This logic is typically implemented in one of the following forms:

  • JDBC Login Module

  • LDAP Login Module

  • Windows Login Module

  • Custom JAAS Login Module

Authentication occurs on a per-request basis. The container typically checks every request to a web application and authenticates it.

Authentication requires that the roles that the application developer defines for a web application be enforced by the server that hosts the application.

As part of developing and deploying an application, you must configure the following application authentication settings:

  • Access roles to applications

  • Resource protection

  • Application server validation method

The web application's deployment descriptor, web.xml, contains the settings for controlling application authentication. This file is stored in the web application's WEB-INF directory.

Using authentication to control access to applications

To use authentication to prevent unauthorized access to your application, you typically use the container to set up constraints on resources. You then challenge the user who then submits credentials. These credentials determine the success or failure of the user's login attempt, as the container's authentication logic determines.

For example, you can protect the page that the application is returned with, or protect the SWF file itself. You do this in the web.xml file by defining specific URL patterns, as the following example shows:

 <web-app> 
 	<security-constraint>  
 		<web-resource-collection>  
 			<web-resource-name>Payroll Application</web-resource-name>  
 				<url-pattern>/payroll/*</url-pattern>  
 				<http-method>GET</http-method>  
 				<http-method>POST</http-method>  
 			</web-resource-collection>  
 		<auth-constraint>  
 			<role-name>manager</role-name>  
 		</auth-constraint>  
 	</security-constraint>  
 </web-app>

When the browser tries to load a resource that is secured by constraints in the web.xml file, the browser either challenges the user (if you are using BASIC authentication) or forwards the user to a login page (with FORM authentication).

With BASIC authentication, the user enters a username and password in a popup box that the browser creates. To specify that an application uses BASIC authentication, you use the login-config element and its auth-method subelement in the web application's web.xml file, as the following example shows:

 <web-app> 
 	<login-config>  
 		<auth-method>BASIC</auth-method>  
 		<realm-name>Managers</realm-name>  
 	</login-config>  
 	... 
 </web-app>

With FORM authentication, you must code the page that accepts the username and password, and submit them as FORM variables named j_username and j_password. This form can be implemented in HTML or as an application or anything that can submit a form.

When you configure FORM authentication, you can specify both a login form and an error form in the web.xml file, as the following example shows:

 <web-app> 
 	<login-config>  
 		<auth-method>FORM</auth-method> 
 		<form-login-config>  
 			<form-login-page>/login.htm</form-login-page><form-error-page>/loginerror.htm</form-error-page> 
 		</form-login-config> 
 	</login-config>  
 </web-app>

You submit the results of the form validation to the j_security_check action. The server executing the application recognizes this action and processes the form.

A simple HTML-based form might appears as follows:

 <form method="POST" action="j_security_check">  
 	<table>  
 		<tr><td>User</td><td><input type=text name="j_username"></tr>  
 		<tr><td>Password</td><td><input type=password name="j_password"></tr>  
 	</table>  
 	<input type=submit>  
 </form> 

The results are submitted to the container's JAAS system with base-64 encoding, which means they can be read by anyone that can view the TCP/IP traffic. Use encryption to prevent these so-called "man-in-the-middle" attacks. In both BASIC and FORM authentication, if the user accessed the resource through SSL, the username and password submission are encrypted, as is all traffic during that exchange.

After it is complete, the container populates the browser's security context and provides or denies access to the resource. Flash Player inherits the security context of the underlying browser. As a result, when you make a data service call, the established credentials are used.

When a user fails an authentication attempt with invalid credentials, be sure not to return information about which item was incorrect. Instead, use a generic message such as "Your login information was invalid."

Using RPC services

You can use the RPC services classes—RemoteObject, HTTPService, and WebService—not only to control access to the data that goes into an application, but also to control the data and actions that flow out of it. You can also use service authentication to allow only certain users to perform certain actions. For example, if you have an application that allows employee data to be modified through a RemoteObject call, use RemoteObject authentication to make sure that only managers can change the employee data.

A service-based architecture makes it easy to implement several different security models for your application. You can use programmatic security to limit access to services, or you can apply declarative security constraints to entire services.

When accessing RPC services with Flex tags such as the <mx:WebService> and <mx:HTTPService> tags, your application's SWF file must connect to the service directly, which means that it can encounter security-based limitations. When using RPC services, one of the following must be true:

  • The RPC is in the same domain as the application that calls it.

  • The RPC's host system has a crossdomain.xml file that explicitly allows access from the application's domain.

Using secured services

Secured services are services that are protected by resource constraints. The service itself behaves as a resource that needs authentication and the container defines its URL pattern as requiring authorization.

You might have a protected application that calls a protected resource. In this case, with BASIC authentication and a proxied destination, the user's credentials are passed through to the service. The user only has to log on once when they first start the application, and not when the application attempts to access the service.

Without a proxy, the user is challenged to enter their credentials a second time when the application attempts to access the service.

When you use secured services, keep the following in mind:

  • If possible, use HTTPS for your services when you use authentication. In BASIC and custom authentication, user names and passwords are sent in a base-64 encoding. Using base-64 encoding hides the data only from plain view; HTTPS actually encrypts the data. You can use HTTPS in these cases by making sure HTTPS is set up on your server and by adding a protocol attribute with the value https on the service, and by adding a crossdomain.xml file.

  • To ensure that the WebService and HTTPService endpoints are secure, use a browser window to access the URL you are trying to secure. This should always bring up a BASIC authentication prompt.

  • If the BASIC or custom login box appears but you can't log in, make sure that the users and roles were added correctly to your application server. This is often an error-prone task that is overlooked as the source of the problem.

Making other connections

Flash Player can connect to servers, services, and load data from sources other than RPC services. Some of these sources have security issues that you should consider.

Using RTMP

Flash Player uses the Real-Time Messaging Protocol (RTMP) for client-server communication. This is a TCP/IP protocol designed for high-performance transmission of audio, video, and data messages. RTMP sends unencrypted data, including authentication information (such as a name and a password).

Although RTMP in and of itself does not offer security features, Flash communications applications can perform secure transactions and secure authentication through an SSL-enabled web server.

RTMPT connections are HTTP connections for the client to the server over which RTMP data is tunneled. When a direct RTMP connection is unavailable, the standard and secure channels use RTMPT and tunneled RTMPS connections, respectively, on the RTMP endpoint.

Use the secure RTMP channel to connect to the RTMP endpoint over Transport Layer Security (TLS). This channel supports real-time messaging and server-pushed broadcasts. This channel falls back to tunneled RTMPS when a direct connection is unavailable.

Using sockets

Sockets let you read and write raw binary or XML data with a connected server. Sockets transmit over TCP. Because of this, Flash Player cannot take advantage of the built-in encryption capabilities of the browser. However, you can use encryption algorithms written in ActionScript to protect the data that is being communicated.

Cross-domain access to socket and XML socket connections is disabled by default. Access to socket connections in the same domain of the SWF file on ports lower than 1024 is also disabled by default. You can permit access to these connections by serving a cross-domain policy file from any of the following locations:

  • The same port as the main socket connection

  • A different port

  • The HTTP server on port 80 in the same domain as the socket server

For more information, see the Socket and XMLSocket classes in ActionScript 3.0 Reference for the Adobe Flash Platform.

Using the LocalConnection class

The LocalConnection class lets you develop SWF files that can send instructions to each other. LocalConnection objects can communicate only among SWF files that are running on the same client computer, but they can be running in different applications—for example, a SWF file running in a browser and a SWF file running in a projector. (A projector is a SWF file saved in a format that can run as a stand-alone application—that is, the projector doesn't require Flash Player to be installed since it is embedded inside the executable file.)

For every LocalConnection communication, there is a sender SWF file and a listener SWF file. The simplest way to use a LocalConnection object is to allow communication only between LocalConnection objects located in the same domain because you won't have security issues.

Applications served from different domains that need to be able to make LocalConnection calls to each other must be granted cross-domain LocalConnection permissions. To do this, the listener must allow the sender permission by using the LocalConnection.allowDomain() or LocalConnection.allowInsecureDomain() methods.

It's best not to use the LocalConnection.allowInsecureDomain() method because allowing non-HTTPS documents to access HTTPS documents compromises the security offered by HTTPS. It is best that all Flash SWF files that make LocalConnection calls to HTTPS SWF files are served over HTTPS.

For more information about using the LocalConnection class, see ActionScript 3.0 Developer's Guide .

To facilitate SWF-to-SWF communication, you can also use cross-scripting. For more information, see Cross-scripting.

Using SSL

A SWF file playing in a browser has many of the same security concerns as an HTML page being displayed in a browser. This includes the security of the SWF file while it is being loaded into the browser, as well as the security of communication between Flash and the server after the SWF file has loaded and is playing in the browser. In particular, data communication between the browser and the server is susceptible to being intercepted by third parties. The solution to this issue in HTML is to encrypt the communication between the client and server to make any data captured by third parties undecipherable and thus unusable. This encryption is done by using an SSL‑enabled browser and server.

Because a SWF file running within a browser uses the browser for almost all of its communication with the server, it can take advantage of the browser's built-in SSL support. This lets communication between the SWF file and the server be encrypted. Furthermore, the actual bytes of the SWF file are encrypted while they are being loaded into the browser. Thus, by playing a SWF file within an SSL-enabled browser through an HTTPS connection with the server, you can ensure that the communication between Flash Player and the server is encrypted and secure.

The one exception to this security is the way Flash Player uses persistent sockets (through the ActionScript XMLSocket object), which does not use the browser to communicate with the server. Because of this, SWF files that use sockets cannot take advantage of the built-in encryption capabilities of the browser. However, you can use one-way encryption algorithms written in ActionScript to encrypt the data being communicated.

MD5 is a one-way encryption algorithm described in RFC 1321. This algorithm has been ported to ActionScript, which enables developers to secure one-way data by using the MD5 algorithm before it is sent from the SWF file to the server. For more information about RFC 1321, see www.ietf.org/rfc/rfc1321.txt.

Using secure endpoints

To access HTTP services or web services through HTTPS, you can specify the protocols using "https" in the wsdl or url properties; for example:

 <mx:WebService url="https://myservice.com" .../> 
 <mx:HTTPService wsdl="https://myservice.com" .../>

By default, a SWF file served over an unsecure protocol, such as HTTP, cannot access other documents served over the secure HTTPS protocol, even when those documents come from the same domain. As a result, if you loaded the SWF file over HTTP but want to connect to the service through HTTPS, you must add secure="false" in the crossdomain.xml file on the services's server, as the following example shows:

 <cross-domain-policy> 
 	<site-control permitted-cross-domain-policies="by-content-type"/> 
 	<allow-access-from domain="*.mydomain.com" secure="false"/> 
 </cross-domain-policy>

If you loaded the SWF file over HTTPS, you do not have to make any changes.

Writing secure applications

When you code an application, keep the following topics in mind to ensure that the application you write is as secure as possible.

MXML tags with security restrictions

Some MXML tags trigger operations that require security settings. Operations that trigger security checks include:

  • Referencing a URL that is outside the exact domain of the application that makes a request.

  • Referencing an HTTPS URL when the application that makes the request is not served over HTTPS.

  • Referencing a resource that is in a different sandbox.

In these cases, access rights must be granted through one of the permission-granting mechanisms such as the allowDomain() method or a crossdomain.xml file.

MXML tags that can trigger security checks include:

  • Any class that extends the Channel class.

  • RPC-related tags that use channels such as <mx:WebService>, <mx:RemoteObject>, and <mx:HTTPService>.

  • Messaging tags such as <mx:Producer> and <mx:Consumer>.

  • The <mx:DataService> tag.

  • Tags that load SWF files such as <mx:SWFLoader> and <s:ModuleLoader>.

In addition to these tags and their underlying classes, many Flash classes trigger security checks including ExternalInterface, Loader, NetStream, SoundMixer, URLLoader, and URLRequest.

Remove sensitive information from SWF files

Applications built with Flash share many of the same concerns and issues as web pages when it comes to protecting the security of data. Because the SWF file format is an open format, you can extract data and algorithms contained within a SWF file. This is similar to how HTML and JavaScript code can be easily viewed by users. However, SWF files make viewing the code more difficult. A SWF file is compiled and is not human-readable like HTML or JavaScript.

But security is not obtained through obscurity. A number of third-party tools can extract data from compiled SWF files. As a result, do not consider that any data, variables, or ActionScript code compiled into an application are secure. You can use a number of techniques to secure sensitive information and still make it available for use in your SWF files.

To help ensure a secure environment, use the following general guidelines:

  • Do not include sensitive information, such as user names, passwords, or SQL statements in SWF files.

  • Do not use client-side username and password checks for authentication.

  • Remove debug code, unused code, and comments from code before compiling to minimize the amount of information about your application that is available to someone with a decompiler or a debugger version of Flash Player.

  • If your SWF file needs access to sensitive information, load the information into the SWF file from the server at run time. The data will not be part of the compiled SWF file and thus cannot be extracted by decompiling the SWF file. Use a secure transfer mechanism, such as SSL, when you load the data.

  • Implement sensitive algorithms on the server instead of in ActionScript.

  • Use SSL whenever possible.

  • Only deploy your web applications from a trusted server. Otherwise, the server-side aspect of your application could be compromised.

Input validation

Input validation means ensuring that input is what it says it is or is what it is supposed to be. If your application is expecting name and address information, but it gets SQL commands, have a validation mechanism in your application that checks for and filters out SQL-specific characters and strings before passing the data to the execute method.

In many cases, you want users to provide input in TextInput, TextArea, and other controls that accept user input. If you use the input from these controls in operations inside the application, make sure that the input is free of possible malicious characters or code.

One approach to enforcing input validation is to use the validator classes. Validators ensure that the input conforms to a predetermined pattern. For example, the NumberValidator class ensures that a string represents a valid number. This validator can ensure that the input falls within a given range (specified by the minValue and maxValue properties), is an integer (specified by the domain property), is non-negative (specified by the allowNegative property), and does not exceed the specified precision.

In typical client-server environments, data validation occurs on the server after data is submitted to it from the client. One advantage of using validators in Flex is that they execute on the client, which lets you validate input data before transmitting it to the server. By using validators, you eliminate the need to transmit data to and receive error messages back from the server, which improves the overall responsiveness of your application.

You can also write your own ActionScript filters that remove potentially harmful code from input. Common approaches include stripping out dollar sign ($), quotation mark ("), semi-colon (;) and apostrophe (') characters because they have special meaning in most programming languages. Because Flex also renders HTML in some controls, also filter out characters that can be used to inject script into HTML, such as the left and right angle brackets ("<" and ">"), by converting these characters to their HTML entities "&lt;" and "&gt;". Also filter out the left and right parentheses ("("and ")") by translating them to "&#40;" and "&#41;", and the pound sign ("#") and ampersand ("&") by translating them to "&#35" (#) and "&#38" (&).

Another approach to enforcing input validation is to use strongly-typed, parameterized queries in your SQL code. This way, if someone tries to inject malicious SQL code into text that is used in a query, the SQL server will reject the query.

For more information on potentially harmful characters and conversion processes, see https://www.sei.cmu.edu/library/2000-tech-tip-understanding-malicious-content-mitigation-for-web-developers/.

For more information about validators, see Validating Data.

ActionScript

Use some of the following techniques to try to make your use of ActionScript more secure.

Handling errors

The SecurityError exception is thrown when some type of security violation takes place. Security errors include:

  • An unauthorized property access or method call was made across a security sandbox boundary.

  • An attempt was made to access a URL not permitted by the security sandbox.

  • A socket connection was attempted to an unauthorized port number, for example, a port below 1024, without a policy file present.

  • An attempt was made to access the user's camera or microphone, and the request to access the device was denied by the user.

Flash Player dispatches SecurityErrorEvent objects to report the occurrence of a security error. Security error events are the final events dispatched for any target object. This means that any other events, including generic error events, are not dispatched for a target object that experiences a security error.

Your event listener can access the SecurityErrorEvent object's text property to determine what operation was attempted and any URLs that were involved, as the following example shows:

<?xml version="1.0" encoding="utf-8"?> 
<!-- security/SecurityErrorExample.mxml --> 
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark"> 
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
 
    <fx:Script><![CDATA[ 
        import flash.net.URLLoader; 
        import flash.net.URLRequest; 
        import flash.events.SecurityErrorEvent; 
        import mx.controls.Alert; 
 
        private var loader:URLLoader = new URLLoader(); 
        
        private function triggerSecurityError():void {   
            var request:URLRequest = new URLRequest("c:/temp/feeds.txt"); 
            
            // Triggers a security exception if you run this SWF from a server without 
            // explicitly allowing local file-access permissions. 
           try { 
                loader.load(request); 
           } catch (error:SecurityError) { 
                Alert.show(error.name + ": " + error.message);                         
           } 
        } 
    ]]></fx:Script> 
 
    <s:Button id="b1" label="Click Me To Trigger Security Error" click="triggerSecurityError()"/> 
 
</s:Application> 

If no event listeners are present, the debugger version of Flash Player automatically displays an error message that contains the contents of the text property.

In general, try to wrap methods that might trigger a security error in a try/catch block. This prevents users from seeing information about destinations or other properties that you might not want to be visible.

Suppressing debug output

Flash Player writes debug output from a trace() method or the Logging API to a log file on the client. Any client can be running the debugger version of Flash Player. As a result, remove calls to the trace() method and Logging API calls that produce debugging output so that clients cannot view your logged information.

If you use the Logging API in your custom components and classes, set the value of the LogEventLevel to NONE before compilation, as the following example shows:

 myTraceTarget.level = LogEventLevel.NONE;

For more information about the Logging API, see Using the logging API.

Using host-based authentication

IP addresses and HTTP headers are sometimes used to perform host-based authentication. For example, you might check the Referer header or the client IP address to ensure that a request comes from a trusted source.

However, request headers such as Referer can be spoofed easily. This means that clients can pretend to be something they are not by settings headers or faking IP addresses. The solution to the problem of client spoofing is to not use HTTP header data as an authentication mechanism.

Using passwords

Using passwords in your application is a common way to protect resources from unauthorized access. Test the validity of the password on the server rather than the client, because the client has access to all the logic in the local SWF file.

Never store passwords locally. For example, do not store username and password combinations in local SharedObjects. These are stored in plain-text and unencrypted, just as cookie files are. Anyone with access to the user's computer can access the information inside a SharedObject.

To ensure that passwords are transmitted from the client to the server safely, enforce the use of SSL or some other secure transport-level protocol.

When you ask for a password in a TextArea or TextInput control, set the displayAsPassword property to true. This displays the password as asterisks as it is typed. This also prevents copy/paste operations from accessing the underlying characters in the text field.

Storing persistent data with the SharedObject class

Flash Player supports persistent shared objects through the SharedObject class. The SharedObject class stores data on users' computers. This data is usually local, meaning that it was obtained with the SharedObject.getLocal() method.

Each remote sandbox has an associated store of persistent SharedObject directory on the client. For example, when any SWF from domain1.com reads or writes data with the SharedObject class, Flash Player reads or writes that object in the domain1.com object store. Likewise for a SWF from domain2.com, Flash Player uses the domain2.com store. To avoid name collisions, the directory path defaults to the full path in the URL of the creating SWF file. This process can be shortened by using the localPath parameter of the SharedObject.getLocal() method, which allows other SWF files from the same domain to access a shared object after it is created.

Every domain has a maximum amount of data that a SharedObject class can save in the object store. This is an allocation of the user's disk space in which applications from that domain can store persistent data. Users can change the quota for a domain at any time by choosing Settings from the Flash Player context menu. When an application tries to store data with a SharedObject class that causes Flash Player to exceed its domain's quota, a dialog box appears, asking the user whether to increase the domain quota.

Configuring client security settings

Some security control features in Flash Player target user choices, and some target the modern corporate and enterprise environments, such as when the IT department would like to install Flash Player across the enterprise but has concerns about IT security and privacy. To help address these types of requirements, Flash Player provides various installation-time configuration choices. For example, some corporations do not want Flash Player to have access to the computer's audio and video hardware; other environments do not want Flash Player to have any read or write access to the local file system.

Three groups can make security choices: the application author (using developer controls), the administrative user (using administrator controls), and the local user (with user controls).

About the mm.cfg file

You configure the debugger version of Flash Player by using the settings in the mm.cfg text file. You must create this file when you first configure the debugger version of Flash Player.

The settings in this file let you enable or disable trace() logging, set the location of the trace() file's output, and configure client-side error and warning logging.

For more information, see Editing the mm.cfg file.

About the mms.cfg file

The primary purpose for the security configuration file (mms.cfg) is to support the corporate and enterprise environments where the IT department wants to install Flash Player across the enterprise, while enforcing some common global security and privacy settings (supported with installation-time configuration choices).

On operating systems that support the concept of user security levels, the file is flagged as requiring system administrator (or root) permissions to modify or delete it. The following table shows the location of the mms.cfg file, depending on the operating system:

Operating System

Location of mms.cfg file

Macintosh OS X

/Library/Application Support/Macromedia

Windows XP/Vista

C:\WINDOWS\system32\Macromed\Flash

Windows 2000

C:\WINNT\System32\Macromed\Flash

Windows 95/98/ME

C:\WINDOWS\System\Macromed\Flash

Linux

/etc/adobe

You can use this file to configure security settings that deal with data loading, privacy, and local file access. The settings include:

  • FileDownloadDisable

  • FileUploadDisable

  • LocalStorageLimit

  • AVHardwareDisable

About FlashPlayerTrust files

Flash Player provides a way for administrative users to register certain local files so that they are always loaded into the local-trusted sandbox. Often an installer for a native application or an application that includes many SWF files will do this. Depending on whether Flash Player will be embedded in a nonbrowser application, one of two strategies can be appropriate: register SWF files and HTML files to be trusted, or register applications to be trusted. Only applications that embed the browser plug-ins can be trusted—the stand-alone players and standard browsers do not check to see if they were trusted.

The installer creates files in a directory called FlashPlayerTrust. These files list paths of trusted files. This directory, known as the Global Flash Player Trust directory, is alongside the mms.cfg file, in the following location, which requires administrator access:

  • Windows: system\Macromed\Flash\FlashPlayerTrust (for example, C:\winnt\system32\Macromed\Flash\FlashPlayerTrust)

  • OS X: app support/Macromedia/FlashPlayerTrust (for example, /Library/Application Support/Macromedia/FlashPlayerTrust)

These settings affect all users of the computer. If an installer is installing an application for all users, the installer can register its SWF files as trusted for all users.

About the Settings Manager

The Settings Manager allows the individual user to specify various security, privacy, and resource usage settings for applications executing on their client computer. For example, the user can control application access to select facilities (such as their camera and microphone), or control the amount of disk space allotted to a SWF file's domain. The settings it manages are persistent and controlled by the user.

The user can indicate their personal choices for their Flash Player settings in a number of areas, either globally (for Flash Player itself and all applications built with Flash) or specifically (applying to specific domains only). To designate choices, the user can select from the six tab categories along the top of the Settings Manager dialog box:

  • Global Privacy Settings

  • Global Storage Settings

  • Global Security Settings

  • Flash Player Update Settings

  • Privacy Settings for Individual Websites

  • Storage Settings for Individual Websites

Access the Settings Manager for your Flash Player

  1. Open an application in Flash Player.

  2. Right-click and select Settings.

    The Adobe Flash Player Settings dialog box appears.

  3. Select the Privacy tab (on the far left).

  4. Click the Advanced button.

    Flash Player launches a new browser window and loads the Settings Manager help page.

Navigation

Using Flex » Application architecture

Adobe, Adobe AIR and Adobe Flash Player are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States and/or other countries and are used by permission from Adobe. No other license to the Adobe trademarks are granted.