Security Error when trying to communicate with Twitter from Flex - apache-flex

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.

Related

Multiple sasl authentication mechanisms in Wildfly 24 with Elytron

I've set up Wildfly to use OAUTHBEARER auth mechanism for remote JNDI EJB lookups between my server and a desktop app, and it works great.
However, I also want to set up a simple .properties file based auth method to communicate with the server without a token to be able request one, or access information about the keycloak auth server as i don't want to hardcode it into my client application, and I can't seem to make it work. Whatever I do, the server rejects my auth attempts.
The sample code I was trying to reach the a pre auth bean with looks like this:
private static PreAuth lookUpPreAuthBean() throws NamingException
{
final Properties jndiProperties = new Properties();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");
jndiProperties.put(Context.PROVIDER_URL,"http-remoting://localhost:8080");
jndiProperties.put(Context.SECURITY_PRINCIPAL, "test");
jndiProperties.put(Context.SECURITY_CREDENTIALS, "test");
final Context initialContext = new InitialContext(jndiProperties);
return (PreAuth) initialContext.lookup("ejb:server/server-ejb/PreAuthImpl!co.my.package.server.PreAuth");
}
Here is the stacktrace I get:
Suppressed: javax.security.sasl.SaslException: ELY05019: No token was given
at org.wildfly.security.mechanism.oauth2.OAuth2Client.getInitialResponse(OAuth2Client.java:66)
at org.wildfly.security.sasl.oauth2.OAuth2SaslClient.evaluateMessage(OAuth2SaslClient.java:62)
at org.wildfly.security.sasl.util.AbstractSaslParticipant.evaluateMessage(AbstractSaslParticipant.java:225)
at org.wildfly.security.sasl.util.AbstractSaslClient.evaluateChallenge(AbstractSaslClient.java:98)
at org.wildfly.security.sasl.util.AbstractDelegatingSaslClient.evaluateChallenge(AbstractDelegatingSaslClient.java:54)
at org.wildfly.security.sasl.util.PrivilegedSaslClient.lambda$evaluateChallenge$0(PrivilegedSaslClient.java:55)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at org.wildfly.security.sasl.util.PrivilegedSaslClient.evaluateChallenge(PrivilegedSaslClient.java:55)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.lambda$handleEvent$1(ClientConnectionOpenListener.java:459)
at org.jboss.remoting3.EndpointImpl$TrackingExecutor.lambda$execute$0(EndpointImpl.java:991)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1348)
at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1280)
at java.base/java.lang.Thread.run(Thread.java:829)
Suppressed: javax.security.sasl.SaslException: DIGEST-MD5: Server rejected authentication
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Authentication.handleEvent(ClientConnectionOpenListener.java:760)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Authentication.handleEvent(ClientConnectionOpenListener.java:602)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:89)
at org.xnio.nio.WorkerThread.run(WorkerThread.java:591)
If I was to supply a token, the bearer mechanism works, seems like for some reason the other mechanism is not authenticating
Here are the parts from the Wildfly 24 standalone.xml I've modified:
EJB subsystem:
...
<default-security-domain value="other"/>
<application-security-domains>
<application-security-domain name="other" security-domain="ApplicationDomain"/>
</application-security-domains>
...
Elytron subsystem:
I would like to use the PreAuthRealm for the simple auth.
<security-domains>
<security-domain name="ApplicationDomain" default-realm="JWTRealm" permission-mapper="default-permission-mapper">
<realm name="JWTRealm" role-decoder="jwt-to-roles"/>
<realm name="PreAuthRealm" role-decoder="groups-to-roles"/>
</security-domain>
...
<\security-domains>
I want to use the application-users.properties file to store the username and the password, these credentials were added to the store with the add-user.sh script
<security-realms>
<identity-realm name="local" identity="$local"/>
<properties-realm name="PreAuthRealm">
<users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="PreAuthRealm"/>
<groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</properties-realm>
<token-realm name="JWTRealm" principal-claim="*my claim*">
<jwt issuer="*my issuer*" audience="account">
<key kid="*my key id*" public-key="*my public key*"/>
</jwt>
</token-realm>
</security-realms>
The sasl authentication factory setup:
<sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
<mechanism-configuration>
<mechanism mechanism-name="OAUTHBEARER">
<mechanism-realm realm-name="JWTRealm"/>
</mechanism>
<mechanism mechanism-name="DIGEST-MD5">
<mechanism-realm realm-name="PreAuthRealm"/>
</mechanism>
</mechanism-configuration>
</sasl-authentication-factory>
Remoting subsystem:
<subsystem xmlns="urn:jboss:domain:remoting:4.0">
<http-connector name="http-remoting-connector" connector-ref="default" sasl-authentication-factory="application-sasl-authentication"/>
</subsystem>
The strange part is, if I remove the sasl-authentication-factory="application-sasl-authentication" from the Remoting subsystem, and put back the original security-realm="ApplicationRealm" the above code runs and it actually authenticates me from the .properties file, but then of course the bearer token part won't work, which is the whole point.
What am I missing with my setup here? Is it even possible what i want to achieve?
Not a solution, but a workaround. Managed to make it work by not naming the realm "PreAuthRealm" but naming it the default "ApplicationRealm", and for whatever reason setting this realm as the default realm in the security domain makes this, and the JWT realm, work. Setting the "JWTRealm" as default only makes the JWT realm work.

swfupload won't allow me to upload from a server to another one

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!

Is there a way to grab a webpage with Actionscript??? I get a SecurityError

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.

Flex: Security error trying to access Google Checkout

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

Flex security error, cannot load data

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");

Resources