Monthly Archive for May, 2007

PHP 4.4.3 supported in SVN

Thanks to Larry Mahony, who reported the bug, I've now fixed SWX so that it should work correctly on PHP 4.4.3. The fix is in the trunk of the SWX SVN repository and will be incorporated into the next Beta release too.

Thanks again, Larry! :)

Cross-domain data exchange in SWX Beta 1 and an issue with mod_security

My friend, Folkert Hielema, who is building a Flash-based Twitter client called SWeetX with SWX, ran into an issue with SWX Beta 1 and the Apache mod_security module that he has also provided a workaround for. I want to share it with you here in case your host also has mod_security installed.

Cross-domain data exchange in SWX back-story

In SWX Beta 1, the way SWX Data SWFs handle allowDomain() has changed, although existing code will still work as it did.

Previously, if you enabled allowDomain in the SWX config file on the server (in other words, allowed cross-domain data exchange from your SWX gateway), the SWX Data SWFs would have a line in them that read System.security.allowDomain(_parent._url);. What this essentially means is: "Regardless of which domain I am loaded from, allow my parent SWF to have access to my contents." That's all fine and dandy but, due to the way sandbox security works, it meant that the parent SWF would also have to allow the SWX SWF access to itself (or else the SWX SWF would not be able to access _parent.) It's all a little chicken and egg but the end result was that you were allowing the SWX SWF access to the main SWF and this was something I was not comfortable with (as it doesn't need access to the main SWF for anything else.)

So, in Beta 1, I added a new way of achieving the same result that doesn't require the main SWF to allow the SWX data SWF access to itself.

The new method for cross-domain data exchange in SWX Beta 1

Starting with SWX Beta 1, if you want to exchange data with your SWX gateway from different domains you have a new workflow available that involves two steps:

Firstly, you set the allowDomain option in the SWX configuration file to true. Secondly, you send an argument in your SWX call named url and set its value to _url (the URL of the calling SWF.) So, for example you could have a line of code that reads:

dataHolder.url = _url;

When using the Full API, this is handled for you.

When you do this, the resulting SWX data SWF will have a line in it that reads System.security.allowDomain('http://the.url.to.your/calling.swf');. As this does not access _parent, you do not need to allow the SWX data SWF access to the main movie.

This new workflow does not replace the old method. If you do not specify a url parameter in your data holder, SWX will default to the old method of using _parent._url in the allowDomain call in the SWX data SWF. In other words, existing code will work as usual.

The mod_security issue

Folkert discovered that mod_security doesn't like a URL being passed as one of the arguments to the SWX gateway. The actual error he got was similar to the following:

[Fri May 25 11:44:34 2007] [error]
[client XX.XX.XXX.XX] mod_security: Access denied with code 403. Pattern match "!/imp/login\\.php" at HEADER("Referer") [id "300018"] [rev "3"] [msg "Generic PHP code injection protection via ARGS"] [severity "2"] [hostname "mydomain.com"] [uri "/php/swx.php?url=http%3A%2F%2Fmydomain%2Ecom%2Fswx%2FsweetX%2Eswf&debug=true&service
Class=Twitter&method=publicTimeline&args=%5Bnull%5D"] [unique_id "PyzB4lNikW4AAFdCLVIAAAAE"]

The Generic PHP code injection protection via ARGS rule in the default mod_security rules that was triggered is the following:

#really broad furl_fopen attack sig
#tune this for your system
SecRule REQUEST_URI "!(/tiki-objectpermissions|aardvarkts/install/index|/do_command|banner_click|wp-login|tiki-view_cache|/horde/index|/horde/services/go|/goto|gallery2?/main|ad-?server/adjs)" "chain,id:300018,rev:3,severity:2,msg:'Generic PHP code injection protection via ARGS'"
SecRule REQUEST_URI "\.php(3|4|5)?(\?|&)" chain
SecRule ARGS "(ht|f)tps?:/"

The rule in question is labeled as being "really broad" and there is a note there that it should be tuned to your system. In fact, there are exceptions in the default file for common web applications like Wordpress, the Tiki wiki and Horde.

Workarounds

The first workaround, of course, is to alter the mod_security rule, above, to include SWX in the list of exceptions. I haven't tested this, but adding |swx to the list of exceptions should do this. Unfortunately, not everyone will have access to this on a shared account, which brings me to the second workaround, provided (and successfully used) by Folkert: use .htaccess.

To disable mod_security for all SWX calls, add the following lines to your .htaccess file:

<IfModule mod_security.c>
    <Files swx.php>
        SecFilterInheritance Off
    </Files>
</IfModule>

Update: Another workaround is to disable mod_security completely. Again, in the .htaccess file, you can use:

#Disable mod_security as it doesn't work with Flash file uploads and some SWX APIs
SecFilterEngine Off
SecFilterScanPOST Off
#End disable mod_security

Note that for uploads to work with the Flickr API, you must disable mod_security using the above lines in an .htaccess file placed in the /flickr/upload/ folder of SWX PHP.

Update: Another workaround (thanks again to Folkert) is to add the URL to swx.php in your exclude.conf file and remove just the rule that's causing the problem, as below:

<LocationMatch "path/to/swx.php">
    SecFilterRemove 300018
</LocationMatch>

A look ahead to cross-domain data exchange in SWX

Cross-domain data exchange is a very important feature in SWX. Among other things, it allows API publishers to create public SWX gateways that can be accessed directly from Flash using SWX. Looking ahead, and in light of this issue with mod_security, I foresee that there will be one more change to cross-domain data exchange and security work in SWX.

Starting with the next beta, there will be a third way to give cross-domain access to the SWX gateway: This time by using a whitelist on the server side.

In the SWX configuration file (swx_config.php), there will be an array of allowed domains that you can edit. Something along the lines of:

$allowedDomains = array ('http://aralbalkan.com', 'http://swxformat.org');

These domains, then, will be written into SWX data SWF files (if the $allowDomain setting is set to true).

Again, this method will not replace the other two methods outlined above but it will provide a third alternative.

The advantage of this method is that you will not need to send a url parameter from the client or allow access to the SWX data SWF. So, it requires the least amount of work from the client. This is the best solution for non-public SWX gateways where you know the exact URLs of the SWF files that will access it.

The disadvantage of this method is that there will be multiple System.security.allowDomain calls in all resulting SWX data SWF files, thereby increasing the size of these files if there are too many domains listed. (So this is not the ideal solution for a public SWX gateway).

In summary

There are currently two ways to allow cross-domain data exchange in SWX and, with the next beta, that number will be three. These are:

  1. Use System.security.allowDomain(dataHolder); on the client to allow the loaded SWX data SWF access to the main SWF and do nothing else. (The SWX data SWF will allow access to itself from the main SWF using System.security.allowDomain(_parent._url))
  2. Do not allow the SWX data SWF access to the main SWF file but pass the url of the current SWF to the SWX gateway by adding it to the data holder (dataHolder.url = _url;). The SWX data SWF will allow access to itself to the url that was passed to the gateway.
  3. Do not allow the SWX data SWF access to the main SWF file or pass a URL from the client but rather add a list of allowed domains to the SWX configuration file on the server.

Cross-domain data exchange is always a hairy topic as it brings with it the Flash sandbox security model. I believe that these three methods will give you the flexibility you need in implementing cross-domain data exchange with SWX without too much difficulty. At the end of the day, we're lucky that we actually can do cross-domain data exchange, unlike technologies like Ajax that cannot.

Thanks again to Folkert for uncovering the mod_security issue and for providing the workaround.

SWX Beta 1 Release

SWX Beta 1.0 is now available for download.

Read more about this release in this post and on the download page.

Heads up: Changing public SWX gateway to latest Beta 1 version

I'm updating the SWX gateway on swxformat.org to the latest Beta 1 version that I am about to release within the next hour or so. This change should not require any client-side changes in your SWX applications.

The main changes here are that your applications will not need to call System.security.allowDomain() on the loaded SWX SWF data files. Instead, if you are not using the SWX API, you will need to pass a url parameter into your data holder movie clip and set its value to _url. The SWX server, after validating that this is a valid URI, will use it in the allowDomain() statement it places in the SWX data SWF to allow your application to access its data. This is a much better way of doing things than the previous method which used (_parent._url) and meant that your application had to allow the SWX data SWF access to itself also. Although you should never place any sensitive data in a SWF, this approach makes more sense in terms of security.

If you do not set a url parameter in your data holder, SWX will function as it did before and you will need to specifically allow domain the data holder movie clip (i.e., your existing apps should continue to work regardless of whether you use the new method or the old.) The Full API in the Beta release uses the new method.

Also, there is now a cancelAllCalls() method in the Full API that you can use to cancel all outstanding SWX calls in the queue.

Cross-domain issue in SVN fixed

I deployed the Beta 1 SWX gateway to swxformat.org yesterday and my twitter badge on aralbalkan.com promptly stopped working. This was because I had mistakenly removed the System.security.allowDomain call in the main SWF. This call is currently necessary because, if allowDomain is on in the SWX server config file, the created data SWF using _parent._url in its own allowDomain call. Of course, it needs access to the parent SWF for this call to succeed so the parent SWF has to, in turn, grant it access. That's not really ideal as the data SWF doesn't otherwise need access to the parent SWF. I'm looking into a better way of doing this by actually writing out the URL of the parent SWF into the returned data SWF and want to include this in Beta 1.

In the meanwhile, though, if you have deployed examples that stopped working yesterday, please either add System.security.allowDomain(gatewayUrl); to your examples (if you didn't already have it) or update from svn and use the full API, which will do this for you automatically.

Heads up: Major API change to affect public SWX gateway shortly

In a few moments, and ahead of the Beta 1 package release, I will be deploying the Beta 1 build of the SWX server to swxformat.org in order to make sure that those sample files that use the public gateway work correctly.

There is one big API change in Beta 1 that will affect all existing SWX applications that are running off the public SWX gateway on swxformat.org (http://swxformat.org/php/swx.php).

The arguments property for your data holder movie clips is now args. This change was made for two reasons: One, arguments is a reserved word and, although it doesn't clash with the built in arguments object (for method calls), I still didn't feel right using it. The second reason is to make it consistent with the new SWX full API in Beta 1. See this post for an example of the full API (note: I just updated that post to reflect this API change so it will be slightly different to how it was yesterday).

I will amend this post with an update once this is done. Please update your applications accordingly once the public gateway is upgraded.

This change (of course) will not affect any local development versions of the SWX gateway you may have until you upgrade to SWX Beta 1.

Update: I'm still updating all the sample apps (of which there are multiple versions to demonstrate usage without the api, with the minimal api and the full api) so this, along with the beta release, is going to be delayed to tomorrow).

Update: I've updated the gateway on swxformat.org to the Beta 1 version. Please implement the API change outlined above in your applications if you are hitting the public gateway here.

SWX Analyzer fix and heads up on today’s the Beta 1 release

The SWX Analyzer was displaying a redundant root array (data). I've now fixed this in SVN and will issue an official release later on today.

At the same time as this release, I will be removing the public SWX gateway on aralbalkan.com. If you are currently using this, please switch to the official public SWX gateway on swxformat.org: http://swxformat.org/php/swx.php.

Finally, if you're using the SWX Twitter API, please note that the method signature for the getNumFriendsUpdates call has changed. The order of the parameters is now friend name first, then (optionally), the number of updates to receive (up to the default, which is 20.) This used to be the other way around but I changed it since the friend name is a required argument and must come first.

Update: Instead of the Alpha 0.3 release as planned, I will be releasing Beta 1 today (May 15th, 2007) this week. See this post for more information.

SWX Twitter API for Flash and Flash Lite

I just documented the SWX Twitter API for Flash and Flash Lite on the official Twitter Development Talk group.

You can read more about this on my blog.

SWX Alpha 0.2.2 Release

SWX Alpha version 0.2.2 is now available for download.

Read more about this release in this post and on the download page.




Bad Behavior has blocked 3746 access attempts in the last 7 days.