When a Cross-Domain Policy File is not Enough
This post is a reminder to myself (and a source of help to anyone who may need it). For a long time I thought a cross-domain policy file in a web server’s root directory solves all cross-domain security issues automagically - until I stumbled over the fact that I wasn’t able to manipulate the bitmap data of an image that was loaded from outside my SWF file’s domain.
Let’s say you want to load a PNG file from “my.domain.com” into a SWF file on “your.domain.com”. Let’s also assume you have provided a “crossdomain.xml” file on “my.domain.com” that grants access to “your.domain.com”. As long as you only add an instance of the flash.display.Loader class to the display list everything is fine. But what if you, for example, want to access the bitmap data inside the loader object? In my case, I just wanted to set the smoothing property of the Bitmap object to true before resizing the image. So I tried this:
-
package
-
{
-
import flash.display.*;
-
import flash.events.*;
-
import flash.net.URLRequest;
-
-
public class Main extends Sprite
-
{
-
public function Main():void
-
{
-
var loader:Loader = new Loader();
-
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, onComplete );
-
loader.load( new URLRequest( "http://my.domain.com/image.png" ) );
-
}
-
-
private function onComplete( event:Event ):void
-
{
-
var bitmap:Bitmap = event.target.loader.content as Bitmap;
-
bitmap.smoothing = true;
-
bitmap.width = bitmap.width / 2;
-
bitmap.height = bitmap.height / 2;
-
addChild( bitmap );
-
}
-
}
-
}
This works fine inside the Flash CS3 IDE (or whatever IDE you use). I deployed the SWF file to a web server - and it failed. Why? Probably because I have missed to read this article, this blog post, and this blog post. And yes, I admittedly have never paid attention to the existence of the flash.system.LoaderContext class. But this class is all what we need here (forget all the PHP proxy hacks, folks!).
Create a LoaderContext object with checkPolicyFile set to true and add it to the flash.display.Loader’s load() method!
-
package
-
{
-
import flash.display.*;
-
import flash.events.*;
-
import flash.net.URLRequest;
-
import flash.system.LoaderContext;
-
-
public class Main extends Sprite
-
{
-
public function Main():void
-
{
-
var loaderContext:LoaderContext = new LoaderContext();
-
loaderContext.checkPolicyFile = true;
-
-
var loader:Loader = new Loader();
-
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, onComplete );
-
loader.load( new URLRequest( "http://my.domain.com/image.png" ), loaderContext );
-
}
-
-
private function onComplete( event:Event ):void
-
{
-
var bitmap:Bitmap = event.target.loader.content as Bitmap;
-
bitmap.smoothing = true;
-
bitmap.width = bitmap.width / 2;
-
bitmap.height = bitmap.height / 2;
-
addChild( bitmap );
-
}
-
}
-
}
It’s easy when you know it.
Tags: ActionScript, Flash, Security
September 11th, 2008 at 6:02 pm
I’ve heard some good things about this blog. Remember to balance the pics with the text tho. cheers!
September 13th, 2008 at 9:15 pm
Love your site it is very informative am going to research the other posts to see what else I can learn, cheers! and keep up the great work!
September 19th, 2008 at 4:31 am
Hi, I found your blog on this new directory of WordPress Blogs at blackhatbootcamp.com/listofwordpressblogs. I dont know how your blog came up, must have been a typo, i duno. Anyways, I just clicked it and here I am. Your blog looks good. Have a nice day. James.
October 20th, 2008 at 6:27 pm
Nice article. Thanks.
Eugene
November 11th, 2008 at 12:32 am
I’ve heard some goody things about this blog. Remember to balance the pics with the text tho
but over all very nice post, keep up the good work
January 6th, 2009 at 5:11 am
Fantastic!
This is exactly what I was looking for and it fixed the issue I was having - will have to put it on my blog and reference you!
jkaris