Aug 05 2009
[AS3] Preventing SWFs From Running Locally
UPDATE: You may also refer to Domain Locking SWFs, because by domain locking (site locking) a SWF, you would prevent it from running locally as well.
The Flash platform is a client-side platform. As a client-side platform, it is fairly easy for end-users to get a copy of online-deployed SWFs from the browser’s cache. There are also browser plugins that make this even easier (often requiring only a few mouse clicks), saving end-users the hassle of looking through the browser’s cache for the right file(s) to copy.
Depending on your application, having end-users run your online-deployed SWF locally may not be what you want.
For example, your application may depend on additional online resources to work, and having end-users “accidentally” running your SWF locally may give the wrong impression that it is not working well. This is especially so if the application seems to run offline well enough in the beginning, but starts to throw errors later on (possibly due to an inability to access additional online resources).
Maybe the application can be run well enough locally offline, but you would very much prefer your users to re-visit your website in order to use the application.
Perhaps you have deployed an ad-sponsored application where you get paid for ad impressions. Having end-users save a copy of your SWF locally and running it offline would obviously be detrimental to your ad-based income. Flash game developers should be familiar with this scenario.
Or, you just don’t like the idea of end-users saving a copy of your work and running it locally. Period.
flash.system.Capabilities.playerType
One way to prevent a SWF from running locally is to check the Flash player type being used to run the SWF. The Capabilities.playerType property is read-only and reports:
- “StandAlone” for the stand-alone Flash Player
- “External” for the external Flash Player or in test mode
- “PlugIn” for the Flash Player browser plug-in
- “ActiveX” for the Flash Player ActiveX control used by Microsoft Internet Explorer
Therefore, you can do:
// ** abort if SWF is running locally ** if (Capabilities.playerType == "Standalone" || Capabilities.playerType == "External") { stop(); // for multiple frame applications return; }
However, the check is easily defeated by running the SWF via a web browser, in which case the playerType will be reported as either “ActiveX” (IE) or “PlugIn” (non-IE browsers). The “ActiveX” type is reported as long as the SWF is viewed within the Flash Player ActiveX control, which means not just in Microsoft Internet Explorer but also any other applications that use the same control, usually in SWF-manipulating type of utilities such as SWF-to-EXE, SWF encryption or SWF decompiling applications.
By the way, when the playerType is reported as “External”, it is quite a misnomer since this actually happens when you run a SWF inside the Adobe Flash authoring IDE (it is “internal” rather than “external”, isn’t it?).
flash.system.Security.sandboxType
I recommend the following code to prevent a SWF from running locally:
// ** abort if SWF is running locally ** if (Security.sandboxType != Security.REMOTE) { stop(); // for multiple frame applications return; }
Security.sandboxType is a read-only property. If the SWF is loaded from a remote host, ie it is from an Internet URL, the value is reported by the Flash Player as Security.REMOTE (the SWF is operating under domain-based sandbox rules). Otherwise, the value will be something else – Security.APPLICATION (running as an AIR application), Security.LOCAL_TRUSTED, Security.LOCAL_WITH_FILE or Security.LOCAL_WITH_NETWORK – all indicating that the SWF is running locally.
You would typically place the check at the beginning of your application, before the actual application code has a chance to execute. For example:
package { import flash.display.Sprite; import flash.events.Event; import flash.system.Security; public class Main extends Sprite { public function Main() { // ** abort if SWF is running locally ** if (Security.sandboxType != Security.REMOTE) { stop(); // for multiple frame applications return; } // ** make sure stage is not null ** addEventListener(Event.ADDED_TO_STAGE, init); } private function init(evt:Event):void { // ** main application code begins ** } } }
Basically, the code just says “do nothing if this SWF is not loaded and run from a remote host”. Of course, if you wish, you may modify the code to make the application do something else, such as displaying a friendly message that tells whoever may be trying to run the SWF locally that he shouldn’t. Or, perhaps you can design the application such that it will work from a local machine with a different set of features.
NOTE: This code doesn’t check for an active Internet connection, just whether the SWF is loaded from an Internet URL. The end-user could go offline after the SWF has been loaded, and the sandboxType would still be Security.REMOTE.
DISCLAIMER I: In the very unlikely scenario that Adobe changes the sandbox types in future Flash Player versions such that remotely loaded SWFs no longer always report a sandbox type of Security.REMOTE, your application will fail to work in those future players. This scenario however is very unlikely (but still worth mentioning, just in case). If you wish to hedge and bet that any future alternative remote sandbox types (if they should arise in the first place) would still have the word “remote” in the string reported, this is an alternative code:
// ** abort if SWF is running locally ** if (Security.sandboxType.indexOf(Security.REMOTE) == -1) { return; }
DISCLAIMER II: This is not a foolproof protection against determined hackers. Neither would it help if someone is determined to run your SWF via the browser “locally” by hosting the SWF on a local web server (localhost).








why not just test the current url for having “http://” within it?
That will work too, but I will discuss it in a future post about domain locking SWFs.