Local Shared Object across domains

Posted: 31/10/09

An image of Local Shared Object across domains

A bit about Local Shared Object and privacy

Local Shared Object(LSO), whether you love it or loathe it, is a useful way to store small amounts of data on the client machine, that will persist after the Flash application has been closed. In fact, it persists so well that it has developed a controversial reputation for itself amongst privacy groups; clearing browser cookies, caches and temp folders doesn't get rid of it. That's not to say it's impossible to get rid of - quite the contrary. Any Flash Player user can just right-click on any SWF, select Settings, and then click the Advanced… button to take them through to the Website Storage Settings Panel or link directly to the Website Storage Settings Panel here, and remove some or all of the LSO files left by sites they've visited. There are also third-party privacy applications out there that claim to be able to remove them.

They can also be removed from the command line (Windows platform)

RD /S /Q "C:Users%USERNAME%AppDataRoamingMacromediaFlash Player#SharedObjects"

Regardless, it is my belief that privacy groups should only be concerned about the storage of personally identifiable information and the subversive act of cookie respawning – Where HTTP cookies are recreated after being deleted, using information stored in the LSO. An LSO that stores a user's chosen volume setting, or the point at which the user had scrolled to on a long text field, are perfectly valid examples that do not infringe upon a user's right to privacy, improve user experience, and do not necessarily need to feature in a privacy policy. On the other hand, a Local Shared Object that stores the user's unique ID, and a selection of products that they have recently viewed, could be construed as personally identifiable, and therefore a potential infringement on a user's privacy. Where LSOs are storing personally identifiable information, the privacy policy covering the application or website should feature a note about the use of LSOs and how a user can remove them.

It is my belief that respawing a HTTP cookie from an LSO, in order to continue a session that would have otherwise been destroyed through cookie clearance, is a deliberate attempt to subvert a user's right to destroy a cookie and discontinue a session. I believe it tarnishes a useful Flash Platform feature, and causes a breakdown in trust between the website and the user.

So with that out of the way, we can now look at a cross-domain Local Shared Object implementation.

Using the same Local Shared Object for multiple SWFs/domains

There are two SWFs, being served from different domains, and they both need access to the same LSO. The way Flash Player is configured, an LSO can be accessed by all SWFs on the same domain when the localPath is set to “/”, but this will not allow SWFs served from another domain to access to object – not what is required. To permit both SWFs to reference the same LSO, there has to be a third ‘gateway' or ‘proxy' SWF that will manage communication between the SWFs and its own LSO. The proxy SWF is loaded into both SWFs when they initialise, and they can then call the public methods available within the proxy SWF to store and retrieve data from the LSO. The proxy SWF can be served from either domain, but must be always be loaded from the same domain to ensure it'll work for both SWFs.

Here's an example of what the proxy SWF should look like:

package

{

import flash.display.Sprite;

import flash.net.SharedObject;

/**

* SharedObjectProxy class

*

* Manages storage and retrieval of data from

* a SharedObject.

*

* Usage: Should be loaded into applications

* requiring a common shared object and called

* on its public methods.

*

* @author Jodie O'Rourke

*/

public final class SharedObjectProxy extends Sprite

{

private var _sharedObject:SharedObject;

public function SharedObjectProxy()

{

_sharedObject = SharedObject.getLocal( "myLSO" );

}

/**

* Sets a value in the LSO

*

* @param name Name of the variable to store

* @param value Value of the variable to store

*/

public function store( name:String, value:* ) :void

{

_sharedObject.data[ name ] = value;

var flush:String = _sharedObject.flush();

}

/**

* Retrieves given variable's value from LSO

*

* @param name Name of variable to fetch

* @return Value of requested variable

*/

public function retrieve( name:String ) :*

{

return _sharedObject.data[ name ];

}

}

}

Client SWFs that load the proxy in at runtime can then store data in the LSO:

private var _loader:Loader();

private var _sharedObject:Object;

private function init() :void

{

_loader = new Loader();

_loader.contentLoaderInfo.addEventListener( Event.COMPLETE, onObjectLoaded );

_loader.load( new URLRequest( “http://domain.com/SharedObjectProxy.swf” ), new LoaderContext( true ) );

}

private function onObjectLoaded( e:Event ) :void

{

_sharedObject = e.target.content;

_sharedObject.store( “name”, “Jodie” );

}

Because every client SWF that loads the proxy loads it from the same location, they are all able to store and retrieve data using the same LSO. As stated previously, it is not necessary to go to these lengths to get to SWFs on the same domain to use the same LSO; defining the localPath parameter as “/” when you call the SharedObject.getLocal()method will achieve this. If you leave localPath as null, an LSO will be generated individually for each SWF.

More info about the SharedObject class

Keywords for this post: flash, actionscript 3, local shared object, crossdomain, LSO, proxy