Flex URLStream Security sandbox violation - actionscript-3

I want to get URLStream from MJPG, but I have received Error #2048: Security sandbox violation error in release version.
What I'm trying to do:
Security.allowDomain("*");
Security.allowInsecureDomain("*");
var stream:URLStream = new URLStream();
//receiving this error event in onStreamSecurityError handler:
//Error #2048: Security sandbox violation: {swf} cannot load data from {url}
stream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onStreamSecurityError);
//load method have no loader context option
stream.load(new URLRequest("http://anydomain.com/mjpg/video.mjpg"));
Setting up crossdomain.xml is not the solution cause the application should able to load a stream from any remote server.
As I remember with flash.display.Loader class I set up LoaderContext and application domain. After that flex app can load resources from any domain. But I don't know what to do with URLStream.
Do you have any solution or a workaround of the Error #2048 ?

It's not possible. You can't remotely grant access to another domain, because it's not yours to grant. The allowDomain() function doesn't do that, it does it the other way around:
Lets SWF files in the identified domains access objects and variables in the SWF file that contains the allowDomain() call.
If your SWF is on domain a.com, and you're adding the line Security.allowDomain("b.com") in it, than grants access to a SWF on domain b.com to your SWF. It does not grant you access to domain b.com.
You can find more detailed info on this in the documentation of allowDomain()
AJAX won't let you do that either, or better put, the browser's won't let you. They're all playing by the same rules.
In order to overcome this, you must proxy the request through a server side script sitting on the same domain as your SWF. It can be in PHP with curl, or whatever you find easier. This video explains how and why.

Related

How can I serve crossdomain.xml file on a specific port?

Let me introduce my problem step by step:
I was using a socket connection on the address www.mydomain.com:1925 to provide a chat service for my users. When I moved to cloudflare, I could not connect to port 1925 directly because of the fact that my requests were reaching my origin server over cloudflare and the port was changing.
How did I solve it?
I created a subdomain chat.mydomain.com whose DNS settings point to my origin server not cloudflare. I bypassed cloudflare by this way and I connected my chat service by using chat.mydomain.com:1925 on the browser. So far so good.
Here is the problem.
I am also using Flash and AS3. It is the core of my game on the site. Chat is working on html and my game in flash is in some part of my website. In flash, I was sending scores of players using again a socket connection on www.mydomain.com:1925 by a different namespace.(Since swf's host and url's host matched, I didn't have any problem I think).Since I have changed the domain to chat.mydomain.com:1925, Flash started to request a crossdomain.xml on chat.mydomain.com:1925. There is a crossdomain.xml file on chat.mydomain.com however I cannot serve it from chat.mydomain.com:1925. Here is my code:
Security.loadPolicyFile("https://chat.mydomain.com/crossdomain.xml");
var urlLoader:URLLoader = new URLLoader ();
var url:String = "https://chat.mydomain.com:1925/socket.io/1/";
var request:URLRequest = new URLRequest(url);
request.method = URLRequestMethod.POST;
urlLoader.dataFormat = URLLoaderDataFormat.TEXT;
urlLoader.addEventListener(Event.COMPLETE, completeHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
urlLoader.load(request);
Since flash cannot find crossdomain.xml by getting 404, the requests in my code do not work. How can I solve this problem?
I have solved the problem. The URLRequest was trying to connect https://chat.example.com:1925/socket.io/1/. Since the swf was on the domain https://www.example.com, the swf was asking for https://chat.example.com:1925/crossdomain.xml. The port did not understand the https since it was used for my websocket. So I could not find any way to call this request in the swf. Then, I came up with an idea that I can call this url outside of the swf. Since I needed only handshakeid, I called this function via javascript. After getting the response, I loaded my swf by giving the handshakeid as an argument. That has solved my problem. For ones who need to call a function like this dynamically, they can use ExternalInterface calls. I hope it helps.

AS3: SharedObject is not visible in Administration Console

I created a media server with 'Adobe Media Server Starter 5' on localhost and I am able to connect to it via an AS3 AIR Application. I can see the connection from my Application called 'SimpleServer' in the 'Adobe Media Server Administration Console' and I get a positive feedback about the connection:
Accepted a connection from IP:127.0.0.1, referrer: app:/SimpleServer.swf, pageurl:
I neither get a compile time nor a runtime error when trying to create a new SharedObject, I get no feedback at all. I am using the following code:
var shared:SharedObject = SharedObject.getRemote("HelloWorld", "rtmp://localhost/SimpleServer");
shared.addEventListener(SyncEvent.SYNC, syncEventHandler);
shared.connect(nc);
The NetConnection is created as followed:
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
nc.connect("rtmp://localhost/SimpleServer");
nc.client = this;
I cannot see a SharedObject in 'View Applications' -> 'Shared Objects' and I get no feedback about the creation. It is like the object has never been created. I also tried to set properties on the SharedObject, with no effect:
shared.setProperty("test", false);
Is there a simple solution to this problem or do I have to configure advanced server stuff? Thank you in advance!
As Sunil asked in the comments, is syncEventHandler ever called when you run your code?
To partially answer your questions: No you don't need any specific server-side configuration to be able to retrieve a SharedObject on the client side. Simply make sure your connected to the server before performing any attempt at getting/connecting to a remote shared object.
See this answer for some more informations
Besides, a good practive when attempting to get a remote shared object is also to use the uri from your NetConnection instance:
var shared:SharedObject = SharedObject.getRemote("HelloWorld", nc.uri);

AIR app: navigateToURL throws a SecurityError #2193

I'm trying to port an existing web app (ActionScript 3 only project) to AIR, to run as a standalone application. One of its features is opening urls in a browser window. But calling navigateToURL(new URLRequest(url)) throws this SecurityError:
SecurityError: Error #2193: Security
sandbox violation: navigateToURL:
app:/AIRDigE.swf cannot access
http://www.youtube.com/watch?v=xCPwAr0xnGE.
at global/flash.net::navigateToURL()
when run from Flash Builder 4.
Googling doesn't really help me with this specific error number.
Adobe's reference on Security Sandboxes states that any AIR application running with Security.sandboxType==Security.APPLICATION (which my application uses) should be able to connect to any domain, but apparently that doesn't count for me.
Any ideas?
Thanks, Frank
Sorry folks, this morning I found the answer myself: the url that I passed into the URLRequest had a space in front of it (it was loaded from an xml feed that is evidently producing faulty urls).
So it seems that a url with an invalid protocol causes that error, and putting a trim() around the url fixed it.
I was getting this error because of using double backward slashes in the web link like "http:\\www.youtube.com"
Where as I supposed to use "http:*//*www.youtube.com"
try using URLRequest with navigateToURL
navigateToURL(new URLRequest("http://www.youtube.com"));
UPDATED:
navigateToURL(new URLRequest("http://www.youtube.com"),"blank");

Is there reliable method of ensuring crossdomain policy files have been retrieved for all Facebook image servers?

I've recently started putting together a Facebook Connect AS3 app and retrieving objects and images through the Graph API.
Running anywhere but locally, I receive security errors of the form:
SecurityError: Error #2122: Security sandbox violation: Loader.content: xxxx cannot access http://photos-a.ak.fbcdn.net/xxxx.jpg
A policy file is required, but the checkPolicyFile flag was not set when this media was loaded.
If I add a line of the form:
Security.loadPolicyFile("ht_tp://photos-a.ak.fbcdn.net/crossdomain.xml");
-then I'm fine for that server, but it seems that there are any number of domains with the photos-[letter] format. I've added the one for each in the alphabet - which happily retrieves crossdomain files successfully - but it doesn't seem like a nice solution, and doesn't accommodate any new hosting setups Facebook may will implement in the future.
One thing I'd considered was retrieving the crossdomain policy file on a per image basis, capturing the domain from the image URL before making the image request. Unfortunately, at least via the Graph solution (and I haven't looked too closely at the others), their servers resolve the image url after the request is made, from something more generic like:
ht_tps://graph.facebook.com/[objectId]/picture?type=small&access_token=[accessToken]
Has anyone found a more dependable means of ensuring that images can be retrieved without security sandbox violations? Or do Facebook maintain a definitive list that developers need to keep an eye on?
Thanks!
Load the facebook crossdomains on the initial of your application as below;
Security.allowDomain("*");
Security.allowInsecureDomain("*");
Security.loadPolicyFile("http://graph.facebook.com/crossdomain.xml");
Security.loadPolicyFile("https://graph.facebook.com/crossdomain.xml");
Security.loadPolicyFile("http://profile.ak.fbcdn.net/crossdomain.xml");
Security.loadPolicyFile("https://profile.ak.fbcdn.net/crossdomain.xml");
Security.loadPolicyFile("http://profile.cc.fbcdn.net/crossdomain.xml");
Security.loadPolicyFile("https://profile.cc.fbcdn.net/crossdomain.xml");
Security.loadPolicyFile("http://fbcdn-profile-a.akamaihd.net/crossdomain.xml");
Security.loadPolicyFile("https://fbcdn-profile-a.akamaihd.net/crossdomain.xml");
Security.loadPolicyFile("http://fbcdn-sphotos-a.akamaihd.net/crossdomain.xml");
Security.loadPolicyFile("https://fbcdn-sphotos-a.akamaihd.net/crossdomain.xml");
and then whenever you want to load an image from facebook, set the checkPolicy flag to true using the Loader's LoaderContext as below;
var context:LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
context.checkPolicyFile = true;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadFacebookPhoto);
loader.load(new URLRequest(YOUR_FACEBOOK_PHOTO_URL),context);
private function onLoadFacebookPhoto(e:Event):void
{
addChild(Bitmap(LoaderInfo(e.target).content));
}
Ideally I would guess that you'd want Flash to get the policy file on its own, rather than triggering it with Security.loadPolicyFile. Have you tried simply setting the checkPolicyFile flag for your Loader's LoaderContext?
Alternately, I believe that when you use URLLoader instead of Loader, Flash will request a policy file automatically, so you could try that as well. The tricky thing is that if you use Loader, Flash will let you display what you've loaded even without a crossdomain policy, so it doesn't load one unless you tell it to. When you use URLLoader, the load itself is not allowed unless there's a policy file, so Flash gets it automatically.

AS3 Loading XML from a different domain

I am trying to load an xml file from wikipedia into my flash movie.
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, tweetLoaded);
loader.load(new URLRequest("http://en.wikipedia.org/w/api.php?action=query&rvprop=content&format=xml&pageids="+subNum));
loader.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorFunction);
This works fine when the flash file is run locally but when I upload to my domain it does not seem to work. I have read elsewhere that the cross domain rule does not apply to XML files only to images and other media. Is this true? If not is there a work around so that I can load in XML files from domains other than the one the swf is hosted on?
thanks
EDIT:
Okay I am really confused, my program queries both Bing API and the media wiki API. The Bing api call works fine, I can retrieve the XML search results back from it fine. But the wikipedia call does not work (online). I have tried listening for the Security_Error on the wikipedia call but it does not fire.
Does anyone have any ideas? Losing it a bit.
Thanks so much for you help. In the end i used http://pipes.yahoo.com
I created a pipe that took in an ID number then spat out a JSON object with the title of the corresponding wikipedia page.
which you can use here http://pipes.yahoo.com/wikibyid
For anyone else doing this you need to make sure you access the pipe from the yahoo api URL
http://pipes.yahooapis.com/
as this domain has the crossdomain.xml file.
A workaround is setting up a proxy with some server side language, so your swf loads data from your domain. This proxy forwards the request to the real host and returns the response to the swf. From the flash side, this works transparently.
You could make your proxy more or less sofisticated, but it could be as simple as (in php):
echo file_get_contents($_GET['target_url']);
This is just to give you an idea, you might want to validate the target_url parameter.
Have your swf call this php script and pass target_url as a parameter. Something like this:
var url:String = "proxy.php";
var paramVal:String = encodeURIComponent("http://en.wikipedia.org/w/api.php?action=query&rvprop=content&format=xml&pageids="+subNum);
url += "?target_url=" + paramVal;
loader.load(new URLRequest(url));
Note that for php this will require allowing fopen for urls (similar permissions might be neccesary for other server side technologies). Also, keep in mind this will affect your server bandwith consumption.
PS
Bing works because they have a crossdomain policy file in place to allow access to swfs from other domains.
http://api.bing.net/crossdomain.xml
Wikipedia doesn't have a crossdomain policy file that grants you access from other domains, so you cannot connect directly from your swf.