I'm trying to integrate a Flex app with Google Checkout and code that runs fine on my local machine is throwing a Security Error when I test on my site.
Here's the error:
Warning: Failed to load policy file from https://sandbox.google.com/crossdomain.xml
*** Security Sandbox Violation ***
Connection to https://sandbox.google.com/checkout/api/checkout/v2/request/Merchant/12345 halted - not permitted from http://www.mysite.com/demo/cartTest/main.swf
ERROR (flash.events::SecurityErrorEvent)#0
bubbles = false
cancelable = false
currentTarget = (flash.net::URLLoader)#1
bytesLoaded = 0
bytesTotal = 0
data = (null)
dataFormat = "text"
eventPhase = 2
target = (flash.net::URLLoader)#1
text = "Error #2170: Security sandbox violation: http://www.mysite.com/demo/cartTest/main.swf cannot send HTTP headers to https://sandbox.google.com/checkout/api/checkout/v2/request/Merchant/12345."
type = "securityError"
Error: Request for resource at https://sandbox.google.com/checkout/api/checkout/v2/request/Merchant/12345 by requestor from http://www.mysite.com/demo/cartTest/main.swf is denied due to lack of policy file permissions.
Like I said, it runs fine locally. How can I get around this security error?
To get around this one, I assembled an html form in Flex and then passed it out to the js on the page, had it appended to an empty form on the page and then submitted the form. I'm keeping the form hidden so all of the UI input and actions happen in the swf. I don't love it but I'll live with it.
The crossdomain.xml file is a security constraint generally designed to prevent malicious behaviors. The permissions are different when you run the SWF locally.
If you are making a request to a different domain, that other domain must host a crossdomain.xml file. If they do not, it will not work. Amazon, for example, hosts a crossdomain.xml file.
This prior StackOverflow thread gives you some options.
Also see Curtis Morley's post on crossdomain.xml files.
You're loading an swf from http: and trying to access an https: URL.
By default this will be blocked (error #2170).
To make it work the target domain (the one you're trying to access from Flash) should have a /crossdomain.xml which allows insecure access (secure="false"). The following crossdomain.xml would have worked in your case if only you could make it accessible at the root of your target URL, i.e. https://sandbox.google.com/crossdomain.xml
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="master-only"/>
<allow-access-from domain="*" secure="false"/>
<allow-http-request-headers-from domain="*" headers="*" secure="false"/>
</cross-domain-policy>
More about the secure flag here: http://www.adobe.com/devnet/..../fplayer9_security.html#_Secure_Domain_Lists
Related
I'm having an epic amount of difficulty trying to get a result from a httprequest to a https address.
I'm loading a policy file from the address but I'm still getting the 2048 security error.
I load my policy file like so in my preinitilize handler.
private function preint(e:FlexEvent):void
{
Security.loadPolicyFile("https://api.soundcloud.com/crossdomain.xml");
}
My server gives me back a special token I need and then I try to make a request to the resource I need using a urlrequest and urlloader.
private function getprivatetracks():void
{
var url:String=new String("https://api.soundcloud.com/me/tracks?oauth_token=" + testapplicationparameters["oauth_token"])
var req:URLRequest=new URLRequest()
req.contentType="application/x-www-form-urlencoded"
req.method=URLRequestMethod.GET;
req.url=url;
var loader:URLLoader=new URLLoader()
loader.dataFormat=URLLoaderDataFormat.TEXT;
loader.dataFormat="text";
loader.load(req);
configureListeners(loader);
}
If I trace out the url I'm calling and paste it into a browser I can see the result fine. It's purely a flash thing.
When I run the swf in debug mode from the flex IDE the request works fine. The problem only occurs when the swf is on a server.
I've spend the best part of a day banging my head trying to figure this out.
Could somebody suggest what I might be doing wrong?
I'm guessing I'm lacking some fundamental knowledge about how flash deals with https.
EDIT 1
Error: Request for resource at https://api.soundcloud.com/me/tracks?oauth_token=0000000NBfKiNXEYG00FWTUGAy5Uw68r by requestor from http://myserver/content/flash/soundcloud/sclive.swf is denied due to lack of policy file permissions.
*** Security Sandbox Violation ***
Connection to https://api.soundcloud.com/me/tracks?oauth_token=0000000NBfKiNXEYG00FWTUGAy5Uw68r halted - not permitted from http://myserver/content/flash/soundcloud/sclive.swf
Error #2044: Unhandled securityError:. text=Error #2048: Security sandbox violation: http://myserver/content/flash/soundcloud/sclive.swf cannot load data from https://api.soundcloud.com/me/tracks?oauth_token=0000000NBfKiNXEYG00FWTUGAy5Uw68r.
at sclive/getprivatetracks()[C:\flex_projects\sclive\src\sclive.mxml:74]
at sclive/authorize_result_handler()[C:\flex_projects\sclive\src\sclive.mxml:62]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at HTTPOperation/http://www.adobe.com/2006/flex/mx/internal::dispatchRpcEvent()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\rpc\http\HTTPService.as:763]
at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::resultHandler()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\rpc\AbstractInvoker.as:263]
at mx.rpc::Responder/result()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\rpc\Responder.as:46]
at mx.rpc::AsyncRequest/acknowledge()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\rpc\AsyncRequest.as:74]
at DirectHTTPMessageResponder/completeHandler()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\messaging\channels\DirectHTTPChannel.as:409]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()
EDIT 2
I've tried catching the security error event and checking the url to make sure theres no redirects going on but the handler never gets called! I always get the unhanled exception error even though I've written a handler for it.
It is not advisable to permit HTTP content to access HTTPS content for security reasons.
So, if soundcloud wants to allow HTTP content to access its data, they should specify it in their crossdomain.xml (using the attribute secure="false" in the allow-access-from tag).
However, I've just noticed there is also a crossdomain on http :
http://api.soundcloud.com/crossdomain.xml
So I suggest you to use this URL instead of the HTTPS and it shloud work
When I try to request a token from Twitter:
_consumer = new OAuthConsumer( _consumerKey, _consumerSecret );
var oauthRequest:OAuthRequest = new OAuthRequest( "GET", AppConstants.TWITTER_REQUEST_TOKEN_URL, null, _consumer, null );
var request:URLRequest = new URLRequest( oauthRequest.buildRequest( _signature ) );
var loader:URLLoader = new URLLoader( );
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener( Event.COMPLETE, requestTokenHandler );
loader.load(request);
I get the following Security Error:
Security ERROR: [SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048: Security sandbox violation: http://localhost:3000/bin/testsite.swf cannot load data from http://twitter.com/oauth/request_token?oauth_consumer_key=....."]
Althought I have added the following:
Security.allowDomain("*");
Security.loadPolicyFile("http://twitter.com/crossdomain.xml");
The weird thing is that it doesn't happen when I run my App in Debug mode (from Flash Builder) it just happens when I call my application from localhot:3000 (as I'm using Rails)!
Any ideas?
You're on the right track. The problem here, like with many other web services, is that the crossdomain.xml is not permissive enough. This is true with Twitter's crossdomain.xml and of any domain that doesn't have a crossdomain.xml file.
Here's Twitter's crossdomain.xml.
<cross-domain-policy xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFile.xsd">
<allow-access-from domain="twitter.com"/>
<allow-access-from domain="api.twitter.com"/>
<allow-access-from domain="search.twitter.com"/>
<allow-access-from domain="static.twitter.com"/>
<site-control permitted-cross-domain-policies="master-only"/>
<allow-http-request-headers-from domain=".twitter.com" headers="" secure="true"/>
</cross-domain-policy>
For you to have access to ANYTHING at twitter.com you would have to load your swf from one of the domains listed in allow-access-from. Since you probably aren't loading your swf from api.twitter.com you need to proxy your calls to Twitter's API from a server behind a domain you control. Essentially, you will write most of your code in a server-side language like PHP and make calls to that from your swf.
The reason everything works when debugging is because there's no sandbox security when loading a swf directly from your local filesystem (not from a local or remote server).
Check out the whitepaper on Flash security and crossdomain spec for more detail.
I don't believe that Twitter's crossdomain policy allows any domain to make requests to it. In which case you will need to use a server proxy like mod_proxy or BlazeDS.
we have two webserver and we have dedicated the task between these two servers.
we've decided to put all the asp/aspx page into one server and put an upload.aspx + sql server into another one:
and here is name of the servers :
http://server1.somecompany.com // this is where all the pages reside + swfupload
http://server2.somecompany.com // this is where upload.aspx and sql server resides
and here is the code inside add_item.asp where swfupload gonna call upload.aspx from server2
SWFUpload.onload = function () {
var audio_settings = {
flash_url : "../script/swfupload.swf",
upload_url: "http://server2.somecompany.com/upload.aspx", // this is where swfupload from server1 call server 2
post_params: {
"ASPSESSID" : "{CDDAF2E2-1178-4465-9842-E54751DE8664}",
"HELLO-WORLD" : "Here I Am",
"section" : "sound"
},
when I click upload button swfupload tries to redirect my page to server2.somecompany.com and doesn't do its job properly
but when I change the upload_url : to someting like :
http://server1.somecomapny.com
everything works fine
I know it is something about security issue in swfupload and they have solved it like this but this fixation makes us dazed .
what can I do about it?
regards.
This is a security measure in Flash. You can configure your remote server to accept these requests, however, by including a file called crossdomain.xml in your server's HTML root.
The file should look something like this:
<?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="[ YOUR SOURCE DOMAIN HERE ]" to-ports="80" />
</cross-domain-policy>
If you must allow access from everywhere, replace "[ YOUR SOURCE DOMAIN HERE ]" with an asterisk "*".
For more information, read here: www.adobe.com/devnet/flashplayer/articles/cross_domain_policy.html
Good luck!
I am trying to grab a webpage with actionscript, but keep getting this error (example trying to grab github.com):
[SWF] /get-webpage.swf - 2,708 bytes after decompression
Error: Request for resource at http://github.com by requestor from
http://localhost:4567/get-webpage.swf
is denied due to lack of policy file permissions.
* Security Sandbox Violation *
Connection to http://github.com halted
- not permitted from http://localhost:4567/get-webpage.swf
Is there any way to make that work in Actionscript? How does the crossdomain.xml file play into this? From my understanding, a website puts a crossdomain.xml at their root, specifying that a swf can access their stuff. Is that correct? What do I need to make the above work? The code I'm working with is basically this:
var request:URLRequest = new URLRequest("http://github.com")
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, complete);
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, error);
loader.load(request);
function complete(event:Event):void {
trace(event.target.data);
}
function error(event:SecurityErrorEvent):void {
trace(event.text);
}
With this in the HTML file:
var flashvars = {};
var params = {allowscriptaccess: "always"};
var attributes = {id: "my_flash", name: "my_flash"};
swfobject.embedSWF("/get-webpage.swf", "flash_content", "50%", "50%", "10.0.0", "playerProductInstall.swf", flashvars, params, attributes, swfHasLoadedSir);
Is it possible to get around that security error?
SHORT ANSWER, NO.
MEDIUM ANSWER, NO.
I see that github has a crossdomain xml policy here.
https://github.com/crossdomain.xml
This is the file that flash automatically loads when it tries to content from another domain.
This xml file is saying, only allow flash on github to suck down data. So github has explicitly said that they dont want you using flash to load any Of their content.
<?xml version="1.0" encoding="UTF-8"?>
<cross-domain-policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFile.xsd">
<allow-access-from domain="github.com" />
<allow-access-from domain="gist.github.com" />
<site-control permitted-cross-domain-policies="master-only"/>
</cross-domain-policy>
I think the reasoning for this flash behaviour is so that people + companies will trust flash. I think this mechanism could prevent massive DOS attacks (think of a Flash Banner loaded on a news site hitting say, github, it could cause a massive load).
You could email github and get your domain added to their list in the crossdomain file but that could take sometime and lots of politics.
LONG ANSWER, YES.
You could create a HTTP Proxy using PHP or something this to pull in a webpage.
The PHP or code would have to run on the same domain as you loaded your SWF file from. eg youdomain.com/folder/proxy.php . You would have to basically ask this proxy to fetch you a web page in PHP and return the results back to flash. This whole process is a bit of pain especially if you hare acting with a web service where you have to send parameters or HTTP headers. There are open source PHP proxy files online that you can install.
Good Luck! Back to watching Transformers 2 with Megan Fox. Oh yeah.
I get a really strange security error when trying to load data from one URL to another. Essentially my facebook canvas URL points to http://www.tonyamoyal.com/stuff/path/ and that has an fb:swf tag which points to http://www.tonyamoyal.com/stuff/path/Quiz.swf. The facebook app loads fine but when I try to call a service that resides on another URL, I get a security error:
http://www.tonyamoyal.com/stuff/path/Quiz.swf cannot load data from http://www.somedomain.com/path/path/service.aspx
The cross-domain on tonyamoyal.com is set up to allow all domains to pass. The cross-domain on somedomain.com has a line specifically allowing calls from www.tonyamoyal.com:
<allow-access-from domain="www.tonyamoyal.com" />
Any idea why there would be a security issue here?
At application startup try to load the policy file by doing:
Security.loadPolicyFile("http://www.somedomain.com/crossdomain.xml");