Rootkits For Javascript Environments
Rootkits For Javascript Environments
Rootkits For Javascript Environments
1
A traditional rootkit [7], [8] modifies the user- same-origin policy that isolates web pages that the
program-accessible behavior of the operating system browser retrieved from different origins [11]. In partic-
and escapes detection by interception of the operat- ular, we assume the attacker owns an untrusted domain
ing system’s reflection APIs, for example removing name, e.g. attacker.com, operates a web server, and
itself from the operating system’s list of running pro- possesses a valid HTTPS certificate for attacker.com.
cesses. Analogously, a JavaScript rootkit modifies the We assume the user visits attacker.com where she
bookmarklet-visible behavior of a JavaScript environ- invokes her login bookmarklet, but we do not as-
ment and escapes detection by overriding the native sume that the user mistakes attacker.com for another
JavaScript objects. Because bookmarklets are invoked web site. If the login bookmarklet process normally
once a web page is already loaded, a malicious web prompts the user for a master password, we assume
page is effectively a rootkit to the bookmarklet’s script. the user enters it at the appropriate time in the login
We present attack techniques to corrupt a JavaScript process. We argue this threat model is appropriate for
environment in today’s unmodified browsers. The password managers because their purpose is to help the
simplest technique shadows a native JavaScript ob- user authenticate to multiple sites without revealing a
ject, while the more complex uses explicit JavaScript common password to all the sites.
features [9] to defeat an advanced bookmarklet’s
reflection-based attempts at detecting our rootkit, and 3. Attack Techniques
even to extract the bookmarklet’s full source code,
which sometimes reveals inline secrets. We note that The browser’s security model does not erect trust
the cat-and-mouse game between a malicious page boundaries within a single JavaScript environment.
cloaking its interposed objects and a bookmarklet Therefore, the attacker can employ a number of tech-
attempting to detect them unfortunately favors the niques to disrupt the integrity or confidentiality of
malicious page, which is loaded first. trusted JavaScript running in an untrusted JavaScript
We examined six commercially available login environment. For example, the attacker can shadow the
bookmarklets. Using our JavaScript rootkit techniques, names of native objects and emulate their behavior,
an attacker can fully compromise all six systems and or the attacker can alter the semantics of built-in
extract all of the user’s passwords if the user attempts types by altering their prototype objects. By applying
to use his or her bookmarklet when visiting the at- these techniques to the JavaScript’s reflection API, the
tacker’s web site. In four of the systems, the attacker attacker can hide these modifications from a book-
can construct a rootkit that fools the bookmarklet into marklet that attempts to use introspection to uncover
revealing all of the user’s passwords with a single the rootkit.
click. In the remaining two cases, the attacker’s rootkit Typically, the attacker modifies the JavaScript en-
cannot extract the passwords directly (because the vironment by running malicious JavaScript while the
passwords are never present in the attacker’s JavaScript web page is loading, before the honest JavaScript runs.
environment), but the attacker can corrupt the book- None of the techniques presented in this section escape
marklet’s cross-site scripting filter, which does run the JavaScript sandbox, disrupt JavaScript running in
in the attacker’s JavaScript environment, eventually other security origins, or compromise the user’s oper-
leading to the full compromise of the user’s password ating system. Not all of these techniques work in all
store. browsers, but many of the techniques work in many of
We propose a secure design for login bookmarklets the major browsers.
that does not rely on the untrusted JavaScript environ-
ment for security. We avoid the cat-and-mouse game Shadowing. An attacker can replace native JavaScript
between the bookmarklet author and the attacker’s objects in the global scope by declaring global vari-
rootkit. Our proposed solution is compatible with web ables with the same name as the native objects. For
browsers that comprise 99% of the market and, as a example, suppose the bookmarklet used the following
result of our disclosures, has been adopted by several code to determine whether it was running on bank.com:
of the login bookmarklet vendors.
if (window.location.host == "bank.com")
doLogin(password);
2. Threat Model
In Internet Explorer and Google Chrome, the attacker
The attacker’s goal is to learn the user’s password can disrupt the integrity of this computation by declar-
for an honest site, e.g., bank.com. We consider the web ing a global variable named window whose value is
attacker threat model [10], with a properly enforced an object with a fake location object:
var window = { Using getters and setters, the attacker can emulate
location: { host: "bank.com" } }; the behavior of native objects. For example, in Sa-
fari 3.1, Google Chrome, and Internet Explorer 8, the
When the bookmarklet tries to read the host property attacker can emulate the native location object:
of the native location object, the bookmarklet in-
stead reads the host property of the fake location window.__defineGetter__("location",
object created by the attacker. Notice that the attacker function () {
cannot modify the native location object directly return "https://bank.com/login#";
because assigning to the native location object });
navigates the current frame to that location. window.__defineSetter__("location",
Browsers let web pages override native objects to function (v) { });
help with compatibility. For example, a pre-release Because the attacker can construct the malicious
version of Firefox introduced an immutable JSON JavaScript after seeing the bookmarklet, the attacker
object into the global scope, but this change broke a need only emulate the native objects to the extent
number of prominent web sites that implemented their necessary to fool the bookmarklet.
own JSON object [12]. To avoid breaking these sites,
Firefox changed the JSON object to be mutable (e.g., Prototype poisoning. An attacker can also alter the
overwritable by attackers). behavior of native objects, such as strings, functions,
and regular expressions, by manipulating the prototype
of these objects. For example, suppose the bookmarklet
Emulation. By interacting with an object, the book-
attempts to ensure that a URL begins with either http
marklet could hope to determine whether the ob-
or https using the following regular expression:
ject has been replaced by the attacker. For exam-
ple, the native location object behaves differ- (/ˆhttps?:/i).exec(url)
ently than a shadowing object if the bookmarklet
The attacker can compromise the integrity of this test
assigns to window.location. Consider the value
by modifying the prototype of regular expressions:
of window.location after running the following:
RegExp.prototype.exec =
window.location = "#"; function () { return true; }
If window.location is the native object, the value Instead of calling the native exec function,
will be "https://bank.com/login#" after the the bookmarklet will instead call the attacker’s
assignment. However, if window.location is an function, which erroneously reports that
object shadowing the real location object, the value javascript:doAttack() is a URL that begins
will be "#". Unfortunately, the attacker can emulate with http or https.
the behavior of native objects using getters and setters. Reflection. The bookmarklet author could hope
Most JavaScript implementations, including Internet to detect emulation or prototype poisoning us-
Explorer 8, Firefox 3, Safari 3.1, Google Chrome, and ing JavaScript’s reflection APIs. For example, most
Opera 9.5, support “getter” and “setter” properties. JavaScript implementations provide a native method
If an object obj has a getter for property p, the called __lookupGetter__ that can be used to
expression obj.p results in calling the getter function determine whether a property has been replaced by
and using the return value of the function as the value a getter. Similarly, the bookmarklet author could hope
of the expression. Similarly, if obj has a setter for p, to use a function’s toString property to determine
the assignment obj.p = x calls the setter function if a function has been replaced by the attacker. For
with the value of x as an argument. example, the bookmarklet might test for the existence
Browsers implement getters and setters to let au- of a getter using the following code:
thors of JavaScript libraries extend native objects to
typeof obj.__lookupGetter__(
emulate features available in other browsers. For ex-
propertyName) !== "undefined"
ample, Internet Explorer supports the non-standard
document.all property. To emulate this features Notice that this code carefully uses !== instead
in other browsers, some JavaScript libraries install a of != to avoid the implicit call to valueOf
getter for the all property of document. Getters and and uses typeof instead of comparing directly
setters are also used by JavaScript libraries to provide against undefined because the attacker can redefine
more convenient DOM-like APIs to web developers. undefined to a value of the attacker’s choice [13].
Unfortunately, the attacker can defeat even operator, analogous to the eq? function in LISP, is
this carefully crafted defense by emulating the more predictable and (roughly) compares the identities
reflection API itself. In particular, the attacker of the objects.) If obj is an object defined by the
can replace __lookupGetter__ by altering attack, the attacker can read the entire source code
Object.prototype: of the bookmarklet, including any passwords or keys
stored in the bookmarklet, by defining a valueOf
Object.prototype.__lookupGetter__ =
method on obj as follows:
function() { ... };
functon f() {
Similarly, the attacker can alter the toString
... f.caller.toString() ...}
method of every function by poisoning the
var obj = { valueOf: f };
Function.prototype object.
The bookmarklet author can defend against this tech-
Global variable hijacking. Bookmarklets cannot rely
nique by never calling an untrusted function, but that
on the confidentiality or integrity of global variables
goal is difficult to achieve, especially if the browser
because those variables can be controlled by getters
supports getters and setters. In most browsers, every
and setters. For example, suppose a bookmarklet con-
property read or write could potentially be a function
tained the following statement: var x = "#";. An
call that leaks the bookmarklet’s secrets.
attacker can subvert the integrity of x by adding a
getter and a setter for x in the window object:
4. Case Studies
window.__defineGetter__(
"x", function () { ... }); To evaluate whether these attack techniques are
window.__defineSetter__( sufficient to defeat real-world implementations of login
"x", function (v) { ... }); bookmarklets, we examine six commercially available
Instead of acting like a normal variable, x now behaves bookmarklet-based password managers. We find that
according to the functions defined by the attacker. all six systems are vulnerable to our attacks. Four of
The bookmarklet author can defend against this attack the systems rely on the integrity of native JavaScript
by never using any variables or by wrapping the objects to protect the user’s site-specific passwords.
bookmarklet inside an anonymous function: The remaining two systems run cross-site scripting
filters in the attacker’s JavaScript environment, where
(function () { ... code ... })(); they can be corrupted using our attack techniques.
Notice that this function must be anonymous because The commercial systems we examine are signifi-
otherwise the attacker could install a setter for the cantly more complex than the prototype bookmarklets
name of the function and read its source code by we constructed in our laboratory. For example, the
calling the function’s toString() method. systems often have a substantial server-side compo-
nent that lets users manage their passwords via their
Caller. Wrapping the bookmarklet code in an anony- browsers and several contain a master password so
mous function can lead to another vulnerability. If user’s can log into their password manager from mul-
the bookmarklet ever calls a function defined by the tiple machines. The bookmarklets themselves often
attacker, the attacker can easily obtain a pointer to the retrieve additional JavaScript code from the server to
anonymous function by checking the call stack, and implement encryption or site-specific form filling func-
can then read the function’s source code by calling tions. However, even with all these additional layers of
its toString() method. For example, suppose the complexity, our attack techniques apply directly.
bookmarklet contains the following code:
VeriSign. The first system we examine is VeriSign’s
(function () {
One-Click Sign-In Bookmark [14]. To extract the
... if (obj == "bank.com") ... })();
user’s Facebook password, for example, the attack need
Before comparing objects, the == operator implicitly only shadow the global location object:
calls the valueOf method of each object, a function
var location = {
which the attacker now controls. The attacker can then
hostname: "www.facebook.com",
extract the bookmarklet’s secrets in Internet Explorer,
href: "http://www.facebook.com/" };
Firefox 3, Safari 3.1, and Chrome. (The == operator
is analogous to equals? function in LISP, which can Alternately, the attacker can define a getter for
be overridden by the objects being compared. The === window.location:
window.__defineGetter__(
"location", function() {
return {
hostname: "www.facebook.com",
href: "http://www.facebook.com/"
};});
A variant on this attack extracts all of the user’s
site-specific passwords at once, rather than one per
click. We reported this vulnerability to VeriSign on 10
October 2008, and VeriSign implemented and deployed
the secure design we suggest in Section 5.
MashedLife. MashedLife is a bookmarklet-based Figure 2. 1Password’s iPhone bookmarklet leaks
password manager. The attacker can extract passwords to web sites, so the setup dialog rec-
the user’s bank password by poisoning the ommends using the native application instead.
String.prototype object:
String.prototype.toLowerCase = clicks his or her bookmarklet, the encrypted passwords
function() { return "bank.com"; }; are stored in a global variable named database.
Using the global variable technique, the attacker can
This attack works because the bookmarklet converts
extract all of the user’s encrypted passwords at once:
the site’s host name to lower case before determining
which password to use. We reported this vulnerability window.__defineSetter__("database",
to MashedLife on 10 October 2008 and suggested function (v) { ... });
the secure design we detail in Section 5. MashedLife
Then, the 1Password bookmarklet prompts the user for
deployed our design on 2 November 2008.
a master password by displaying a form within the cur-
Passpack. Passpack is a bookmarklet-based password rent page. This master password is used as a decryption
manager. Passpack’s bookmarklet calls the toString key for the password database. The attacker can over-
method on the current page’s location, letting the at- ride the event handler that the bookmarklet calls after
tacker extract the user’s Delicious password, for exam- the user types their master password and decrypt every
ple, by poisoning the String.prototype object: password in the database using the decryptEntry
function defined by the bookmarklet.
String.prototype.toString =
We reported this vulnerability to 1Password on 12
function() {
October 2008. 1Password has acknowledged that their
return "https://delicious.com"; };
bookmarklet is exploitable as we describe, but has de-
By itself, this attack is not sufficient because Passpack cided not to repair the vulnerability. A dialog displayed
also validates the HTTP Referer header. However, during setup recommends using the 1Password iPhone
they implement lenient Referer validation [15] (they application instead (See Figure 2).
accept requests that lack a Referer header). By using
Clipperz. Unlike the above four bookmarklet-based
one of a number of Referer suppression techniques,
password managers, Clipperz’s bookmarklet does not
the attacker can extract the user’s passwords.
fill out the site’s password form. Instead, the book-
We reported this vulnerability to Passpack on 10 Oc-
marklet helps the user register a new site with the
tober 2008, and Passpack implemented and deployed
Clipperz service. Upon being clicked, the bookmarklet
the secure design we suggest in Section 5 within 20
serializes the contents of the current page’s login
minutes. Passpack has also published a full description
form and displays the raw data in current page. The
of the vulnerability and their patch [16].
bookmarklet then instructs the user to copy and paste
1Password. 1Password, a password manager for Mac- this information into the Clipperz web site. When the
OS-X-based browsers, includes a bookmarklet-based user wants to log in to the site using Clipperz, Clipperz
component designed for the iPhone. Unlike the three uses JavaScript to submit a form with the recorded
systems described above, the 1Password bookmarklet login credentials to the target site, essentially mounting
does not contact its server during the login process. a login cross-site request forgery attack [15] against
Instead, 1Password stores all of the user’s site-specific the target site. Only sites that are vulnerable to login
passwords within the bookmarklet itself. When the user cross-site request forgery can be used with Clipperz.
Because Clipperz creates the cross-site login form bookmarklet issues a network request to pwdmngr.
on the clipperz.com domain, Clipperz sanitizes the com, the password manager server should disclose the
form parameters to prevent cross-site scripting at- user’s bank.com password only if the Referer header
tacks. This sanitization is performed by the book- begins with the string https://bank.com/. If the
marklet during the registration process, but the at- Referer header is absent or contains an unexpected
tacker can circumvent the filter by poisoning the value, the password manager should not disclose the
Array.prototype object: user’s site-specific password. Although some network
operators suppress the header, the Referer header
Array.prototype.join = function() {
is present 99.9% of the time over HTTPS [15], and
... return evilString; }
the password manager should be using HTTPS for
We reported this vulnerability to Clipperz on 13 Oc- transferring the user’s passwords over the network.
tober 2008, recommending that they perform the sani- We propose combining these browser security fea-
tization in the clipperz.com security context. Clipperz tures to implement a secure login bookmarklet. In
patched this vulnerability on 17 October 2008. our design, the bookmarklet itself does not store any
secrets and is identical for all users. The bookmarklet
MyVidoop. MyVidoop uses a design similar to Clip- simply inserts a <script> tag into the current doc-
perz, but instead of relying on the user to paste ument that requests a script from pwdmngr.com over
the serialized form details into the password man- HTTPS. The password manager’s server then validate
ager site, MyVidoop’s bookmarklet sends them to the master secret and Referer header.
myvidoop.com via an HTTP request. As with Clipperz, If the master secret is missing (perhaps because
MyVidoop relies on the bookmarklet to run a cross-site it was evicted or was deleted), the script navigates
scripting filter in the attacker’s JavaScript environment. the user to https://pwdmngr.com/login, where the user
The attacker can evade the filter by poisoning the can enter his or her master passphrase. (In particular,
RegExp.prototype object: the password manager must not prompt the user for
RegExp.prototype.exec = the passphrase in a window under the control of the
function () { return true; } attacker because the attacker can steal the user’s master
passphrase by drawing a malicious password entry
To defend against this attack, MyVidoop should filter control on top of the honest control.)
cross-site scripting attacks on the server. We reported
this vulnerability to MyVidoop on 12 October 2008.
MyVidoop patched the issue on 13 October 2008.
6. Conclusion