Posts Tagged Greasemonkey

Greasemonkey And Dojo Integration Redux

Back in 2007 I wrote a post on how to integrate Dojo with Greasemonkey.
Since then, Greasemonkey has been re-written to include security and bug fixes which has broken my demo code. The problem is that the new security model doesn’t return an instance to the newly created dijit.Dialog when the constructor is called. The work-around is to set the ID of the dialog, and then call dijit.byId() to get a handle to it.

Of course, this is going to pose problems when creating non-dijit objects, as they will all be created on the page-level scope. The work-around is likely constructing clever eval() strings, and then accessing the objects using unsafeWindow. If anyone comes up with a more elegant solution, let me know about it in the comments.

The following can be used to overwrite the previous version of the user-script, restoring the broken functionality as well as making use of some of the newly introduced Dojo features.

// ==UserScript==
// @name           Dojo Integration Test
// @namespace      test
// @description    Proof Of Concept To Integrate Dojo And Greasemonkey
// @include        *
// ==/UserScript==
 
function startup(){
	dojo = unsafeWindow["dojo"];
	dijit = unsafeWindow["dijit"];
 
	dojo.addClass(dojo.body(), 'tundra');
	dojo.require("dijit.Dialog");
 
	//Don't do anything until "Dijit.Dialog" has been loaded
	dojo.addOnLoad(function(){
		//Actually Create The Dialog
		new dijit.Dialog({
			id: 'test',
			title: "Dojo Integration Test",
			content: 'Dojo lives... In Greasemonkey'
		});
 
		dijit.byId('test').show();
	});
};
 
//include flags to djConfig to tell dojo its being used after its been loaded
unsafeWindow.djConfig = {
	afterOnLoad: true,
	addOnLoad: startup
};
 
//Include Dojo from the AOL CDN
var script = document.createElement('script');
script.src="http://o.aolcdn.com/dojo/1.4/dojo/dojo.xd.js.uncompressed.js";
document.getElementsByTagName('head')[0].appendChild(script);
 
//Include the Tundra Theme CSS file
var link = document.createElement('link');
link.rel = "stylesheet";
link.type= "text/css";
link.href="http://o.aolcdn.com/dojo/1.4/dijit/themes/tundra/tundra.css";
document.getElementsByTagName('head')[0].appendChild(link);

, ,

2 Comments

Adblock Plus, Greasemonkey For Firefox 3 Beta 5

I love Adblock Plus – I refuse to use the internet without it. I also quite enjoy Greasemonkey. Unfortunately, neither is yet compatible with the new Firefox 3b5. I got tired of waiting so I took measures into my own hands.

The XPI file format is basically a glorified zip file, so you can unzip it with a compression utility and modify the maximum version number in install.rdf. Basically I replaced the value in the em:maxVersion field with 3.* so to make it compatible with all versions of Firefox.

Of course, these maximum version numbers are there for a reason: newer versions of Firefox may break the extension functionality, but no problems so far.

For the lazy, I have uploaded the patched install files. Of course I give zero guarantees or warranty for the correct operation of these patched extensions. I encourage you to upgrade to the official compatible version as soon as possible.

To install:

  1. Download File
  2. Drag downloaded file into open Firefox window
  3. Enjoy an Ad-free internet

Adblock Plus For Firefox 3 Beta 5 The Adblock Plus Development build now supports Beta 5. Get it here: http://adblockplus.org/devbuilds/

Greasemonkey For Firefox 3 Beta 5

, ,

4 Comments

Cookie Injection Using Greasemonkey

There are several Firefox plugins which allow the user to manipulate their browser cookies. However, most of these plugins force the user to manipulate cookies individually. This can become tedious if the user is simply “importing” cookies from, say, a wireshark dump.

The CookieInjector userscript simplifies this process, by allowing the user to copy-paste the cookie portion of the dump and have the cookies from the dump automatically created on the currently viewed web page.

Updated Cookie Injector Script available on
userscripts-mirror.org

To Use The Script:

Fire up Wireshark, formally Ethereal, if you don’t have Wireshark you can grab it from: http://www.wireshark.org/. Start listening for traffic on the same interface you use to access the internet. To cut down on extra packets, enter tcp as a capture filter. TCP is a transport layer protocol featuring reliable transport, congestion control and connection oriented transfers. Since HTTP uses connections between client and server and therefore the TCP protocol, is is safe to filter out all non-TCP packets. To further filter the packets that Wireshark is displaying enter http.cookie in the filter field. This will filter out all packets which are not using the HTTP application layer protocol and all HTTP packets which do not contain cookies.

Next go to a website that uses cookies. Most websites which support user logins or shopping carts use cookies for these purposes. Make sure that the website that you visit does not encrypt the entire session (such as a banking website), otherwise the packets will be encrypted and not viewable in wireshark. After capturing a couple packets which contain cookies scroll down to the Hypertext Transfer Protocol portion of the packet preview, expand it, and scroll down to the cookie line. Right click on the line, and select copy->Bytes (Printable Text Only). This will copy the human-readable portion of the packet which represents the Cookies associated with this website.

If you haven’t already, install Greasemonkey, and the CookieInjector userscript. Clear your private data, ensuring that the Cookies and Authenticated Sessions options are selected. This will delete all your cookies, so we can see the script in action. Press alt-c to view the CookieInjector dialogue, paste the cookie string from wireshark into the text box and click OK.

Congratulations! Your cookies have now been restored!

How The Script Works:

After the page has loaded the CookieInjector class is initialized. This involves setting up the dialogue and binding a function to the onkeydown event. When the user presses the ALT-C key combination, the CookieInjector keyPress function is called, which checks to see if the correct key combination has been triggered. If it is valid, the dialogue’s display style is changed, making it visible in the middle of the page.

After the user enters the cookie that was copied from Wireshark, the script does a quick cleanup of the string, and then adds the cookies to the browsing session.

Note that the cookie’s host will be the domain that is loaded in the browser when the cookie is injected. The root path will be used for the root of the cookie to ensure that the cookie is persistent across the entire domain. Finally, the cookie is a session cookie, which means that the cookie will expire when the browser is closed.

Security Implications Of Cookies

The use of cookies for identification and authentication presents a dangerous security risk for un-encrypted connections. Most websites (such as Hotmail, Facebook and Gmail), only encrypt the username and password when initially authenticating the user and all traffic following the initial handshake is un-encrypted. As a result, the cookie information is readable by anyone who is listening with appropriate software, and malicious users can steal the cookies of other users on the network, possibly gaining access to their accounts. Un-encrypted or weakly encrypted wireless connections (those which do not use WPA or stronger encryption schemes) are especially susceptible to cookie stealing. This is because anyone with a wireless card can simply listen to all network traffic as it is broadcast through the air, intercepting cookies, images, web pages and any other traffic which may or not be intended for them. Intercepting traffic on a switched network (most LANs) is more complex, but can be accomplished using ARP Poisoning or software such as Ettercap

The take-home lesson is to use encrypted connections, like https, whenever privacy is important. Always remember that if the connection is not encrypted anyone could be listening in.

 

Edit: I have released a new version of the script that should fix the problems with the window appearing in WYSIWYG windows + post data.
Edit: Several people have been reporting the cookie injector window appearing in Gmail emails. All WYSIWYG editors may be affected depending on their implementation. If you experience problems with the cookie injector window showing up where it shouldn’t, edit the userscript to exclude the problem site.

For example, I have updated the userscript to ignore gmail / mail.google.com domains with the following in the header:

// @exclude		   https?://gmail.com/*
// @exclude		   https?://mail.google.com/</del>

Please make the change yourself, or download the new version of the script to suppress its operation on Gmail pages.

External Links:

Greasemonkey: https://addons.mozilla.org/en-US/firefox/addon/748
HTTP Protocol: http://en.wikipedia.org/wiki/HTTP
TCP Protocol: http://en.wikipedia.org/wiki/TCP
Cookies: http://en.wikipedia.org/wiki/HTTP_cookie
Wireshark: http://www.wireshark.org/
Ettercap: http://ettercap.sourceforge.net/
ARP Poisoning: http://en.wikipedia.org/wiki/ARP_spoofing
Ethereal: http://www.ethereal.com/

, , , , , , , ,

47 Comments

Greasemonkey And Dojo Integration

Dojo (http://dojotoolkit.org/) is a wonderful javascript toolkit which just reached version 1.0 at the beginning of November. I have been watching and developing with Dojo for a couple years now and I can’t tell you how excited I am to have passed the version 1 milestone

Greasemonkey (http://www.greasespot.net/) is a handy Firefox extension which allows the injection of javascript (called userscripts) into the webpage currently being viewed. This allows for the customization of the look and feel of a website: improving the user interface or adding additional functionality.

In this example, we are going to use greasemonkey and Dojo to display a dialog widget on an arbitrary website.

To simplify the deployment of a userscript we are going to use the AOL Content Distribution Network to pull in a crossdomain build of the dojo toolkit. This is helpful to us as developers as we don’t have to build or maintain Dojo ourselves and is useful to the user as they get an optimized download from a distributed CDN.

First thing’s first: If you haven’t already, download and install the Greasemonkey extension, and create a new user script.

To access the power of Dojo, we must include the Dojo crossdomain build on the page we are visiting. To do this, we will dynamically create a new script element containing the address of the build and append it to the document head:

var script = document.createElement('script');
script.src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js";
document.getElementsByTagName('head')[0].appendChild(script);

Next, since we are going to need a Dijit Dialog object, we will need to also include the Tundra Theme CSS file by appending it to the head object:

var link = document.createElement('link');
link.rel = "stylesheet";
link.type= "text/css";
link.href="http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
document.getElementsByTagName('head')[0].appendChild(link);

Great! Now we have the Dojo javascript file included on the page as well as the Dijit Tundra theme setup and ready to use. Next, we will actually include the Dojo dependencies we need and display our Dialog!

To ensure that the Dojo Javascript file and the Tundra Stylesheet have been downloaded and parsed we must include the rest of the code in a function that will run when the window fires the “load” event To do this, we will add an event listener to the window object with the function as an argument:

window.addEventListener('load', function(event) {
var dojo =  unsafeWindow["dojo"];
dojo.require("dijit.Dialog");

Also notice that we have created a local variable called Dojo which is a refrence to the unsafeWindow dojo object. Greasemonkey runs all userscripts in a sandbox which provides enhanced security as well as ensures that they do not conflict with any preexisting scripts already on the page. Because, by default, Dojo is instantiated with a visibility relative to the window object it is not visible to our script. By creating a reference to it in a local variable, this allows us to access its functionality.

Also important is the dojo.require statement. This will pull in the dijit.Dialog object which we will be instantiating later on in our script. To ensure that all the dependences have been loaded before we try to create a dialog, we must wait until dojo knows that the external resource has been loaded.

dojo.addOnLoad(function(){
var dijit = unsafeWindow["dijit"];
dojo.addClass(document.getElementsByTagName('body')[0], "tundra");
 
var pane = document.createElement('div');
pane.id = "floatingPane";
pane.innerHTML="Dojo Lives... In GreaseMonkey!";
document.getElementsByTagName('body')[0].appendChild(pane);
 
dialog = new dijit.Dialog({
title: "Dojo Integration Test"
},pane);
dialog.show();
});
}, 'false');

A lot of stuff happens in the above code snippit:
First we grab a local reference to the global dijit object, next we assign a “tundra” class to the body tag, which will allow us to have the correct theme for our Dialog. We create a div node which will eventually become our Dialog, populate it with appropriate attributes and append it to the document’s body tag. Finally we create a new dialog object with a catchy title and the previously created div node as the contents, and display it on screen. Lastly, we close the window.addEventListener object that we created in the previous step.

Downloaded the complete userscript here:
Dojo Integration Userscript This script has been updated and is available here

Special Thanks to Shane Sullivan’s Dojo Debug Script which shows how to access the Dojo object from the Greasemonkey sandbox.

, ,

8 Comments