Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the Flash Player throw a sandbox error in this case?

I get a Flex 3 sandbox error #2048 after connecting to a Socket on a Java (1.5) server. The server code is all mine, i.e. not running under Apache. Flash Player 10.0 r32.

The sequence is as follows...

1 Java server starts, listens on port 843 for policy file request and on port 45455 for my other requests.

2 Flex client served by Apache (although I get the same result if I run it from the file system), socket connection made on host:45455.

3 Flash Player requests policy file from port 843. This is the standard behaviour with the new security settings looking for a master file. It happens regardless of whether a different policy file has been specified.

4 I serve the following XML from Java through port 843:

<?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="all"/>
<allow-access-from domain="*" to-ports="*" secure="false"/>
</cross-domain-policy>

5 The player writes the following into the debug policy log...

OK: Root-level SWF loaded: http://localhost/bst/BasicSocketTest.swf
OK: Searching for <allow-access-from> in policy files to authorize data loading from resource at xmlsocket://192.168.2.3:45455 by requestor from http://localhost/bst/BasicSocketTest.swf
OK: Policy file accepted: xmlsocket://192.168.2.3:843
OK: Request for resource at xmlsocket://192.168.2.3:45455 by requestor from http://localhost/bst/BasicSocketTest.swf is permitted due to policy file at xmlsocket://192.168.2.3:843

6 I send a text message from the client to the server on port 45455 using writeUTFBytes() and flush() (this is my own home-baked message protocol, and is correctly processed at each end)

REG/REGISTER;simon;Si

7 Java server thread listening on port 45455 responds with

REG:0/REGISTER:SUCCESS;simon;Si

8 The Flex client receives a ProgressEvent and the event listener I bound to the socket gets called. I process the message (write it to a text box on the screen)

9 The Flash player throws a 2048 sandbox error and the socket is disconnected! This is after the message is received and processed successfully. In fact it is about 12 seconds after. Nothing else works through the socket.

I have tried explicitly loading a policy file with a call to Security.loadPolicyFile() in the Flex client, but the reality of the new player security is that it is basically ignored. The steps are that the policy request will not get sent until a socket i/o operation occurs. At that point the player always goes to port 843 first looking for a master policy file. If it finds one, and it is permissive, it goes no further.

I have tried a variety of alternative ways of terminating the policy file and policy file contents, including deliberate errors just to see if the Flash Player is awake.

I can see no reason why I would have a 2048 being thrown. I accurately serve a socket policy file on the designated master security port, which the player itself logs as correct. The socket then successfully sends and receives a message from the server the contents of which are available to my code.

Does anyone have any clue why this may be happening? Flash Player bug?

P.S. Please don't tell me to use BlazeDS or LCDS or Granite, or something else as a server, I'm looking for a solution to this problem, not a redesign. And please don't ask me to use an XMLSocket instead - I tried that and get exactly the same result. I have chosen my architecture carefully and deliberately and I want a binary socket.

EDIT In response to James Ward's request in his comment, here is the entire error message:

Error #2048: Security sandbox violation: http://localhost/bst/BasicSocketTest.swf cannot load data from 192.168.2.3:45455.

I have a stripped down test client which has a handler for each socket event and outputs a message to the screen. This is what it shows:

RequestPolicy: 192.168.2.3:843
Create Socket: 192.168.2.3:45455
Connect: [Event type="connect" bubbles=false cancelable=false eventPhase=2]
Sending: REG/REGISTER;[email protected];Si
Receiving: REG:0/REGISTER:SUCCESS;[email protected];Si/
Close: [Event type="close" bubbles=false cancelable=false eventPhase=2]
Error #2048: Security sandbox violation: http://localhost/bst/BasicSocketTest.swf cannot load data from 192.168.2.3:45455.

The close event is fired immediately after successfully receiving a response from the server, however the Error #2048 does not appear until about 20 seconds later. If I try and send a further message after close, but before the error, the Flash Player throws an invalid socket exception.

I have logged a bug at Adobe about this.

I can provide full source code of both client and server if anyone is interested.

like image 930
Simon Avatar asked Nov 10 '09 16:11

Simon


4 Answers

I've been testing this locally and everything seems to be working fine until the socket gets closed. Shouldn't the socket not get closed? After the message is sent to the Flex client, the Java code does:

_in.close();
_out.close();
_socket.close();

Then the Flex client gets the sandbox violation the next time it tries to communicate with the socket. If I create a new socket connection again then send and receive works fine, followed by a close. But after a minute or so I get another sandbox violation. I wonder if Flash is trying to ping the socket and since it's closed it throws the sandbox violation?

like image 82
James Ward Avatar answered Nov 10 '22 02:11

James Ward


Have you tried adding the allow-http-request-headers-from element?

<allow-http-request-headers-from domain="*" headers="*" />

Or specifying the actual ports instead of * for the allow-access-from element?

<allow-access-from domain="*" to-ports="843,45455" />
like image 27
dan_nl Avatar answered Nov 10 '22 02:11

dan_nl


A similar problem here indicates that localhost was not being resolved to 127.0.0.1.

You might try changing over to the IP address and see if that helps.

like image 1
Phil Hayward Avatar answered Nov 10 '22 01:11

Phil Hayward


You might try a few things further in the code with the Security class in addition to yoru crossdomain.xml

Try:

Security.allowDomain("*")
Security.allowInsecureDomain("*")

Or if you are loading from external servers outside the aporoved allowed host:

Security.allowDomain(loader.contentLoaderInfo.url)

Then slowly turn it back on until you hit the error.

Make sure you can hit the policy file directly and there is no block or other app running on that port. Typically when I run sockets I go higher than 5000 just to make sure nothing is using up the port. Or try a few different ports.

Also just as a simple check make sure you named it crossdomain.xml and it is all lower case. I have had programmers pull their hair out and this turned out to be the cause.

like image 1
Ryan Christensen Avatar answered Nov 10 '22 01:11

Ryan Christensen