Home > Tools > Flash cookies

Flash cookies

I wanted more than to just be able to delete their cookies, but to be able to view what information websites were storing about my surfing habits. I know where the cookies live, I know how to open them up, and I want to be able to view them all at once.

If you don’t know about “flash cookies”, you need to go get informed.

I thought it would be ironic to build an adobe air application to find and remove the cookies; and it is done.

In case you don’t want to follow the links:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
					   xmlns:s="library://ns.adobe.com/flex/spark" 
					   xmlns:mx="library://ns.adobe.com/flex/mx"
					   creationComplete="windowedapplication1_creationCompleteHandler(event)" viewSourceURL="srcview/index.html">
	<fx:Script>
		<![CDATA[
			
			
			/**
			 * 
			 * Created by Russ Watson.
			 * https://flex4examples.wordpress.com
			 * 
			 * MIT License: http://www.opensource.org/licenses/mit-license.php
			 * 
			 * TODO:
			 * 	- Logging
			 * 	- TODOs in the code
			 * 	- TODO: Add warning to the user about deleting SOLs out of #SO dir? Are there required SOLs?
			 * 
			 **/
			
			
			
			import flash.events.MouseEvent;
			import flash.system.Capabilities;
			
			import mx.collections.ArrayCollection;
			import mx.controls.Alert;
			import mx.events.FlexEvent;
			import mx.events.ListEvent;
			import mx.utils.ObjectUtil;
			
			private var _myRootSoDir:String;
			
			protected function windowedapplication1_creationCompleteHandler(event:FlexEvent):void
			{
				
				var dir:File = File.userDirectory;
				var os:String = Capabilities.os;
				var sep:String = File.separator;
				switch ( true )
				{
					case os.substr(0, 7) == "Windows":
						dir = File.userDirectory.resolvePath("AppData"+sep+"Roaming");
						if ( !dir.exists )
						{
							dir = File.userDirectory.resolvePath("Application Data");
						}
						dir = dir.resolvePath("Macromedia"+sep+"Flash\ Player"+sep+"#SharedObjects");
						break;
					case os.substr(0, 3) == "Mac":
						dir = dir.resolvePath("Library"+sep+"Preferences"+sep+"Macromedia"+sep+"Flash\ Player"+sep+"#SharedObjects");
						break;
					//Assuming linux
					default:
						dir = dir.resolvePath(".macromedia"+sep+"Flash_Player"+sep+"#SharedObjects");
						break;
				}
				
				_myRootSoDir = File.applicationStorageDirectory.resolvePath("#SharedObjects").nativePath;
				if ( dir != File.userDirectory && dir.exists )
				{
					txtCookiePath.text = dir.nativePath;
					
					//Clear previous session if there was a problem
					var f:File = new File(_myRootSoDir);
					if ( f.exists )
					{
						f.deleteDirectory(true);
						f.createDirectory();
					}
					
					refresh();
				}
				else
				{
					Alert.show("The Flash cookie monster currently doesn't work on " + os, "System Incompatibility")
					enabled = false;
				}
			}
			
			private function refresh():void
			{
				var ac:ArrayCollection = lstCookies.dataProvider as ArrayCollection;
				if ( ac == null )
				{
					lstCookies.dataProvider = ac = new ArrayCollection();
				}
				ac.removeAll();
				
				var dir:File = new File(txtCookiePath.text);
				if ( dir.exists )
				{
					//TODO: How about lets make this asyncronous and show progress?
					findSols(dir, onSolFound);
				}
				else
				{
					Alert.show("Directory does not exist", "Invalid cookie path");
				}
			}
			
			private function onSolFound(sol:File):void
			{
				var ac:ArrayCollection = lstCookies.dataProvider as ArrayCollection;
				
				var dir:File = sol.parent;
				var random:File;
				var site:File;
				
				//Navigate back up to the shared objects directory.
				while ( dir != null && dir.exists && dir.name != "#SharedObjects")
				{
					site = random;
					random = dir;
					dir = dir.parent;
				}
				
				if ( site == null )
				{
					//Currently supporting web based flash apps, which assumes the paths setup at load time based on the user's OS.
					//TODO: Go to the root (last directory user entered), then down one level and you have the application name --
					// at least on MACs...
					ac.addItem({site: "Unknown - Probably an Air application", name: sol.name, sol: sol});
				}
				else
				{
					ac.addItem({site: site.name, name: sol.name, sol: sol});
				}
				
			}
			
			private function findSols(directory:File, solCallback:Function):void
			{
				for each ( var subDirectory:File in directory.getDirectoryListing() )
				{
					if ( subDirectory.isDirectory )
					{
						findSols(subDirectory, solCallback);
					}
					else
					{
						var file:File = subDirectory;
						if ( file.extension == "sol")
						{
							solCallback(file);
						}
					}
				}
			}
			
			private function readSol(sol:File):String
			{
				try
				{
					//Copy to the app's root directory
					var f:File = new File(_myRootSoDir);
					f = f.resolvePath(sol.name);
					sol.copyTo(f, true);
					
					//Inspect the object
					var name:String = f.name.substring(0, f.name.indexOf("."));
					var so:SharedObject = SharedObject.getLocal(name, "/");
					var spec:String = sol.nativePath;
					
					return "Full cookie path: " + spec + "\n" + "Details:" + ObjectUtil.toString(so) + "\n\n"
				}
				catch ( e:Error )
				{
					return "Error reading " + sol.nativePath + "\n" + e.toString();
				}
				return "";
			}
			
			
			protected function lstCookies_changeHandler(event:ListEvent):void
			{
				txtDetails.text = "";
				for each ( var selectedItem:Object in lstCookies.selectedItems )
				{
					txtDetails.text += readSol(selectedItem.sol as File);
				}
				//We are done reading, remove the copy
				var f:File = new File(_myRootSoDir);
				f.deleteDirectory(true);
				f.createDirectory();
			}
			
			
			protected function button1_clickHandler(event:MouseEvent):void
			{
				txtDetails.text = "";
				for each ( var selectedItem:Object in lstCookies.selectedItems)
				{
					var sol:File = selectedItem.sol as File;
					try
					{
						sol.deleteFile();
						txtDetails.text += sol.nativePath + " was successfully deleted.\n\n";
					}
					catch ( e:Error )
					{
						txtDetails.text += "Could not delete: " + sol.nativePath + "\n" + e.toString() + "\n\n";
					}
				}
				refresh();
			}
			
		]]>
	</fx:Script>
	<s:Panel left="0" bottom="0" right="0" top="0" title="Flash Cookie Monster">
		<s:Label text="Cookies" left="5" top="10"/>
		<s:TextInput left="55" top="5" right="85" id="txtCookiePath"/>
		<s:Button label="Refresh" top="5" right="5" click="refresh();"/>
		<s:VGroup left="5" right="5" top="50" bottom="5">
			<s:Label text="Listing" textDecoration="underline"/>
			<mx:DataGrid id="lstCookies" width="100%" height="100%" change="lstCookies_changeHandler(event)" allowMultipleSelection="true">
				<mx:columns>
					<mx:DataGridColumn dataField="site"/>
					<mx:DataGridColumn dataField="name"/>
				</mx:columns>
			</mx:DataGrid>
			<s:Button label="Eat Selected Cookies" left="5" bottom="5" click="button1_clickHandler(event)" toolTip="Deletes the cookie from the hard drive. Permenantly."/>
			<s:Label text="Details" textDecoration="underline"/>
			<s:TextArea id="txtDetails" width="100%" height="100%"/>
		</s:VGroup>
		
	</s:Panel>
</s:WindowedApplication>
Advertisements
  1. March 16, 2011 at 3:35 PM

    Nice work.

    Please add a cool icon and maybe allow selection via checkboxes and BringToFront if a checked cookie changes.

    Cheers

  2. March 17, 2011 at 8:33 AM

    Thanks.

    I added a cookie icon and I’ve started on the file monitoring.

    I’ve uploaded the download link in the post to the new version. If you have the application installed already, you will need to uninstall it first. Moving forward, new installers will ask you to overwrite the existing application, but I upgraded the code to the latest adobe air SDK and used a new temporary install cert.

  3. August 31, 2011 at 8:34 AM

    Thanks for this post! Help me to figure out how to backup and SO onto an SD card on tablets.

    Appreciate it.

    Don Kerr

    • roustalski
      August 31, 2011 at 8:49 AM

      Sorry Don, but I don’t own any tablets, so I’m not sure how you access the file system there – either through code or the OS interface.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: