Flash AS3 - URLLoader cant load binary data from different domain - actionscript-3

Two important points.
1 - SWF must have ability to loading binary data from any domain.
2 - SWF cant load policy XML file from url, cause upload form allows me only to upload swf files, so I cant include any other data.
I tried:
Security.allowDomain("*");
But it works only for SWF files.
I tried to embed policy XML file:
var dataXML:XML =
<?xml version="1.0"?>
<!-- http://www.foo.com/crossdomain.xml -->
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>;
But Security.loadPolicyFile(url:String) allows only to set file url, not data.
So my question is, how can I allow SWF to load binary files from different domains without having any additional file?
URLLoader code:
var request:URLRequest = new URLRequest("http://differentdomain.com/binaryfile.dat");
var words:URLLoader = new URLLoader();
words.dataFormat = URLLoaderDataFormat.BINARY;
words.addEventListener(Event.COMPLETE, prepareFile);
words.addEventListener(IOErrorEvent.IO_ERROR, loadError);
words.addEventListener(SecurityErrorEvent.SECURITY_ERROR, secureError);
words.load(request);
This will make an security error, if file is from different domain than SWF file.
Thanks for any help.
Its possible to get binary data from JavaScript using ExternatInterface in AS3 code.
Here is cross-browser library for reading files binary: binary reader and later version jDataView
Hope this will help someone.
Thanks to Jonatan Hedborg for idea.

You should read this before : http://kb2.adobe.com/cps/142/tn_14213.html
And you can use a proxy script, search on google/stackoverflow you'll find a lot of answers...

Take a look at this: http://wonderfl.net/c/gJXA
Some trick which works with any binary data from any domain, without need to use ajax or own proxy script (sometimes you dont have possibility to upload php scripts).

Flash is control that most commonly used by HTML pages. As result it needs to follow security restrictions places on other (i.e. JavaScript) objects on the same page.
Web pages use same origin security policy - objects on a page can't read data from domains different from domain of the current page.
There are cases when servers for other domains allow such access. I.e. in Flash case it is crossdomain.xml, similar policy file exist for Silverlight, there are several ways to handle it for JavaScript including JSONP.
Incorrect usage of ways to bypass same origin policy leads to cross-site scripting issues on your site/page that host your control which often leads to leaking personal information.

I had to tackle a similar problem a while ago and managed to make use of UrlStream to load the target SWF's bytes at runtime.
gist: https://gist.github.com/1988661

Related

Local SWF file running in a browser within dropbox cannot access remote file security sandbox violation - Cross Domain Policy

I'm using dropbox to distribute large swf files with corresponding html files that load the swfs. All the large swf files access a small "Key" swf in the same folder as the html file. That all works fine. But when the large swf files also try to access a remote text file on my server I get a security sandbox violation. After reading about this, I see that this is by design for security reasons.
But there has to be a way around this without having the user authorize the domain containing the txt file. The reason I say this is because the swf files are running right from the browser on the persons computer. I then thought about a cross domain policy. Not sure what it would look like since it's a local computer that's asking. I hope this makes sense. I was hoping I could put the cross domain policy (or some other file) on the users computer right along with the other files, but I don't think that's what they're for.
This is an update to the question above as my problems relate to crossdomain policy's. I'm showing a small snippet of code that is causing this error shown in Debug mode in the Flash IDE. The code eventually gets the txt file loaded, but is delayed due to the warning I believe and I'm wondering if this can be fixed? The delay is causing an issue.
Attempting to launch and connect to Player using URL C:\Users\Jeffrey\Dropbox\Photos\ABC\bopAnimationSales\testingGettingVariablesFromExternalSWF_simplestForm3.swf
[SWF] C:\Users\Jeffrey\Dropbox\Photos\ABC\bopAnimationSales\testingGettingVariablesFromExternalSWF_simplestForm3.swf - 21834 bytes after decompression
Warning: Domain www.postureviewer.com does not specify a meta-policy. Applying default meta-policy 'master-only'. This configuration is deprecated. See http://www.adobe.com/go/strict_policy_files to fix this problem.
Complete
[UnloadSWF] C:\Users\Jeffrey\Dropbox\Photos\ABC\bopAnimationSales\testingGettingVariablesFromExternalSWF_simplestForm3.swf
Debug session terminated.
Here's the code:
import flash.events.*;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.system.Security;
//flash.system.Security.loadPolicyFile("http://www.postureviewer.com/trials/crossdomain.xml");
var urlRequest:URLRequest = new URLRequest("http://www.postureviewer.com/trials/jeffaberle.txt" + "?" + Math.random()); // + Math.random()
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, completeHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
urlLoader.load(urlRequest);
function completeHandler(e:Event):void {
trace("Complete");
}
function ioErrorHandler(e:IOErrorEvent):void {
trace("ioErrorHandlerJeff: " + e.toString());
licenseKeyNotFoundScreen.visible = true;
}
To authorize your local swf file to access to a remote content ( a text file in your server in your case ), you don't need a crossdomain.xml file that
grants a web client—such as Adobe Flash Player, Adobe Reader, etc.—permission to handle data across multiple domains
So in your case, when using a local swf to get data from a remote location, you have just to add your swf to the list of trusted locations like I explained in my answer of this question.
Hope that can help.
You can load a cross domain policy from an arbitrary location via "loadPolicyFile"
I would recommend hosting it at the same location as the remote text file to keep things simple, i.e.
http://www.example.com/clients/clientfile.txt
http://www.example.com/clients/crossdomain.xml
Then in the 'big' SWF, import the Flash Security package if you are not using it already:
import flash.system.Security;
Then before making any calls remote calls to load data content from your local based SWF, call loadPolicyFile:
flash.system.Security.loadPolicyFile("http://www.example.com/clients/crossdomain.xml");
Then you will be able to call URLRequest, etc... without any issues:
urlRequest = new URLRequest("http://www.example.com/clients/clientfile.txt");
Your crossdomain.xml should look like this:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="www.example.com/clients"/>
</cross-domain-policy>
PS: An online cross domain generator is # http://www.crossdomainmaker.com Helps prevent typos and that painful head scratching when yours does not work... ;-)
PSS: Personally for local SWFs, I prefer AIR packaging as it eliminates the cross-domain issues, no browser is required, etc... Only one file that contains all your other SWFs as resources that can be deploy as an '.air' file or via a native Windows installer (exe) or OS-X dmg and .app installer.

Crossdomain policy behaviour on 302 redirects in AS3

I have crawled the web quite a lot these days, but couldn't get any accurate information on how crossdomain.xml files behave in case of 302 redirects; especially with the sandboxes having changed significantly over the last versions!
I am relatively new to flash... so any advice is more than appreciated!
I have been working on a project lately that uses audio streams with some sort of CDN distribution! what happens is that a common url is triggered, and then the user is dynamically redirected to the next best server available. In my case, i have no access at the server side of things (at least not anytime soon). And the only path providing an appropriate crossdomain.xml is the one performing the redirect. All the other dynamic paths provide exclusively content!
http://resource.domain.com (valid crossdomain.xml)
302 => http://dyn1.domain.com/...
302 => http://dyn2.domain.com/...
302 => http://dyn3.domain.com/...
I noticed that flash doesn't care much if i try to load the audio stream with something like...
var req :URLRequest = new URLRequest("http://resource.domain.com");
var sound :Sound = new Sound(req); // ie. effectively playing http://dyn3.domain.com
sound.play();
It gets both redirecting, and streaming done well! and doesn't bother for any crossdomain file and starts playing!
Although when i try something different, like setting up some custom headers to the request and loading the file with URLStream instead, everything gets messy! Well, the redirect gets done, as expected but all of a sudden i need another crossdomain file in the redirected location!
Is there any explanation to whats happening and eventually ways to resolve this?!
Thanks for your time!
It comes as a site question : i noticed everything to work flawlessly while being in the local-trusted sandbox and errors happening mainly if not exclusively in the remote sandbox. is it possible that the local-trusted sandbox doesn't care about crossdomain policy files at all!?
Summary
Add crossdomain.xml to each CDN host or adopt to limited Sound functionality.
Details
SWF files that are assigned to the local-trusted sandbox can interact with any other SWF files and can load data from anywhere (remote or local).
Sound can load stuff from other domains that don't allow access using cross-domain policy with certain restrictions:
Certain operations dealing with sound are restricted. The data in a
loaded sound cannot be accessed by a file in a different domain unless
you implement a cross-domain policy file. Sound-related APIs that fall
under this restriction are Sound.id3, SoundMixer.computeSpectrum(),
SoundMixer.bufferTime, and the SoundTransform class.
Flash in general has pretty complex cross-domain policies but in your case the bottom line is that you'll need to have proper crossdmain.xml on each host except the one that serves the SWF:
3.1. If your file is served from http://resource.domain.com it's not required to have http://resource.domain.com/crossdomain.xml but it's really good to have one.
3.2. You will need to have proper http://dyn2.domain.com/crossdomain.xml explicitly allowing your SWF to access dyn2.domain.com to be able to use URLLoader and other APIs that provide access to raw loaded data.
3.3. There's a reason for these restrictions - cookies (and other ambient user credentials). If Flash would not require proper cross-domains after a redirect, one could access any domain with user cookies attached by simply loading his own redirector first. This means accessing all user cookie-protected data (e.g. mail.google.com) from any SWF on the internet that's running in your browser.

ActionScript3 Error Handling URLRequest

(ActionScript3) Hi, I'm trying to work out why a URLRequest is failing when viewed via a third party website. Ideally any error could be pointed out in the below code, however, I think it's fine as similar things we do work fine.
Next to ideal would be URLRequest error handling, how can I find out WHY the URLRequest is not pulling the information from time.php? Even if it's just output to a textbox on the timeline (everything works fine when done from the testing environment)
Many thanks
Craig
Scenario:
domain.com (Server 1): file.swf uses a URLRequest to load domain.com/time.php?a=b (so the PHP and the SWF are both hosted on the same domain and server)
example.com (Server 2): PHP page embedding file.swf (which in turn URLRequests time.php)
Outcomes:
When you access file.swf directly via browser, it loads the data from time.php just fine
When you view the page file.swf is embedded on, on Server 2 the loading fails
file.swf
var loaderNameHolder;
var loaderNameHolderLoader:URLLoader = new URLLoader();
var loaderNameHolderURLRqst:URLRequest = new URLRequest('http://domain.com/time.php?a=b');
loaderNameHolderLoader.addEventListener(Event.COMPLETE, loaderNameHolderURLFunc);
loaderNameHolderLoader.load(loaderNameHolderURLRqst);
function loaderNameHolderURLFunc(e:Event):void{
loaderNameHolder = loaderNameHolderLoader.data
gotoAndStop(loaderNameHolder);
}
Security
There is a crossdomain XML in place on the domain's root folder, it seems to make no difference (or is not being referenced/used correctly) however as mentioned similar things I do work fine without modifying this XML
It sounds like a security issue, although you say that you have the crossdomain file in place.
Have you checked the http calls with a tool like Charles (http://www.charlesproxy.com/)? This is definitely the best way to debug such a problem.
Thanks for the tips above, they'll be great resources to keep.
The actual issue was that the Requested URL didn't include "www" (I think because the SWF is embedded with the WWW so it was coming from an "outside" domain. I think I need www.domain.com in my own security XML).
Craig
try adding this code
Security.allowDomain("*");
Security.loadPolicyFile("http://domain.com/crossdomain.xml");
and read about crossdomain.xml using links given here: https://stackoverflow.com/a/9728845/2234089

Load an image in flash/actionscript from a different origin domain

I'm a complete noob when it comes to flash coding.
I have a flash swf file that I'm loading from an S3 assets bucket. Inside the flash swf it should be displaying a "Browse" button, images also courtesy of the same bucket. This works fine when I host the images and swf file from the same domain that the site is on, but not when loaded from S3.
I have added a crossdomain.xml file to the assets bucket as follows (I'm trying with '*' to start just to get it working, and will narrow it down to my actual host when it appears to be doing anything):
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>
I also have a cross-origin resource sharing configuration in the bucket so that the fonts will correctly load for our stylesheets (This is working).
What am I doing wrong to make the button images load in the actionscript? Do I need to modify the actionscript code itself? The code is located here (public library anyone can use, not authored by me): s3-swf-upload-plugin
You can see here that it is instantiating a new browseButton defined here. Like I said I'm not totally familiar with actionscript but believe I could fumble through it if someone could show me what's going wrong :) What's a good way to get actual error reporting? Firebug in Firefox and Chrome's console don't have any kind of messages from Flash about errors going on.
EDIT:
There were some quirkinesses going on in the setting up of the flash object and setting the paths for the button images. I updated BrowseButton.as to do this:
Security.loadPolicyFile("http://s3.amazonaws.com/my-bucket/crossdomain.xml");
I placed this before any of the URLRequest calls in the BrowseButton() function. However it's still not displaying the images :( I also hardcoded the values in the URLRequest to be things like:
upLoader.load(new URLRequest("http://s3.amazonaws.com/my-bucket/assets/s3_up_button.gif"));
but nothing seems to happen. When I set it to /assets/s3_up_button.gif to pull from the local file then it works fine. What am I doing wrong! How can I get error messages displaying from the flash video? :\ I compiled with <debug>true</debug> but I'm not sure how to get actual exception messages.
Check what sandbox your swf is in:
The Security.sandboxType property
An author of a SWF file can use the read-only static
Security.sandboxType property to determine the type of sandbox to
which Flash Player has assigned the SWF file. The Security class
includes constants that represent possible values of the
Security.sandboxType property, as follows:
Security.REMOTE--The SWF file is from an Internet URL, and operates under domain-based sandbox rules.
Security.LOCAL_WITH_FILE--The SWF file is a local file, but it has not been trusted by the user and was not published with a networking designation. The SWF file can read from local data sources but cannot communicate with the Internet.
Security.LOCAL_WITH_NETWORK--The SWF file is a local file and has not been trusted by the user, but it was published with a networking designation. The SWF can communicate with the Internet but cannot read from local data sources.
Security.LOCAL_TRUSTED--The SWF file is a local file and has been trusted by the user, using either the Settings Manager or a Flash Player trust configuration file. The SWF file can both read from local data sources and communicate with the Internet.
You probably want Security.LOCAL_WITH_NETWORK, although Security.LOCAL_TRUSTED will also work.
An explanation, along with details of how to set the sandbox in Flex, is here: http://livedocs.adobe.com/flex/3/html/help.html?content=05B_Security_04.html
If you're working in the Flash IDE, it should just be part of the publish settings.

Writing Flash crossdomain.xml for Amazon S3

I have two servers. Server A is an internal server that has access from the outside world set up here in my office. It has a Rails server running on it. I have a second server, Server B, that contains all our static content (images, swfs, javascript, css, etc.), it is an Amazon S3 server. I have given all these files public access.
What I am attempting is to put a swf from Server B on a page served by Server A. Then, the other assets that the swf requires in order to display get dynamically loaded from Server B. Unfortunately, however, somewhere along the way it's failing and the files that are requested to be dynamically loaded just never arrive.
Based on errors in my browser console the swf is expecting a crossdomain.xml file to be on Server A. Based on this, it also needs one to be on my S3 server. So, that being the case I have created two crossdomain.xml files, one for each server.
This is Server A's crossdomain.xml file:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="s3-bucket-name.s3.amazonaws.com" />
</cross-domain-policy>
This is Server B's crossdomain.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="master-only"/>
<allow-access-from domain="*.server-a.com"/>
<allow-http-request-headers-from domain="*.server-a.com" headers="SOAPAction"/>
</cross-domain-policy>
Additionally, I am explicitly loading Server B's crossdomain.xml file in my swf:
Security.loadPolicyFile("https://s3-bucket-name.s3.amazonaws.com/crossdomain.xml");
No matter what I do, however, it just does not work. I'm not sure what else to try. I've tried looking through a number of the solutions here on SO but nothing has helped me resolve my problem yet. Surely someone else has had more experience in this than I have and can give me some guidance, I'm pretty much out of ideas at this point.
Update
Updating my question with some more info.
I tried setting both policy files to * and it started working until it hit:
SecurityError: Error #2121: Security sandbox violation: Loader.content: s3.amazonaws.com/bucket_name/swfs/foo.swf cannot access s3.amazonaws.com/bucket_name/data/swfs/bar.swf. This may be worked around by calling Security.allowDomain.
Additionally, I ran Charles and it is pulling the crossdomain.xml from both my local server but I don't see it for s3.
Update 2
I tried adding this to the loader:
var context:LoaderContext = new LoaderContext();
context.securityDomain = SecurityDomain.currentDomain;
context.applicationDomain = ApplicationDomain.currentDomain;
Loader.load(new URLRequest(_dataFile), context);
This resulted in the files actually downloading! Unfortunately now it crashes out with this:
SecurityError: Error #2119: Security sandbox violation: caller s3.amazonaws.com/bucket_name/swfs/MainSwf.swf cannot access LoaderInfo.applicationDomain owned by s3.amazonaws.com/bucket_name/data/swfs/foo/SecondSwf.swf
I've tried including/not including the context.applicationDomain = ApplicationDomain.currentDomain; line but that hasn't resolved the issue.
Where the crash is actually occurring is at a later time after the file is loaded where we are getting the applicationDomain: loader_.contentLoaderInfo.applicationDomain.getDefinition( def.a )
Make sure the mime type of crossdomain.xml is set to application/xml. Flash will not load the policy file if the mime type isn't set correctly. Checkout CloudBerry's free s3 client, it's pretty good at detecting/setting the correct mimetype, its possible the s3 client you're using didn't set it correctly.
Edit: Apache, and other webservers, detect a file's mime type and return it in the response headers - so this issue doesn't normally come up in local testing
Solved, finally. Make sure you're using the bucket name as the subdomain for both the Policy file loading, and every file / URL request.
Solution:
http://onegiantmedia.com/cross-domain-policy-issues-with-flash-loading-remote-data-from-amazon-s3-cloud-storage
It looks like you have a.swf and b.swf on different domains, and a.swf is trying to access the content of b.swf (via Loader.content), and no doubt it's failing with a security error.
You have two options:
Load b.swf in the same security domain as a.swf (i.e. the "current" security domain). You can do this in a.swf's code by passing a new LoaderContext to Loader.load() and setting the loaderContext.securityDomain = SecurityDomain.currentDomain
Explicity allow a.swf to access b.swf by calling Security.allowDomain() in b.swf's code with a.swf's domain name as the parameter
Which one you choose depends on other considerations. With the first one, b.swf is able to do what a.swf can do (everything!) in terms of cross-domain security (i.e. access files, etc.); with the second one, any SWF file on a.swf's domain is able to access b.swf's content. It really depends how you want to set up the trust.