Cross-Origin JavaScript Capability Leaks: Detection, Exploitation, and Defense

Page created by Clara Rivera
 
CONTINUE READING
Cross-Origin JavaScript Capability Leaks:
                            Detection, Exploitation, and Defense
             Adam Barth                         Joel Weinberger                      Dawn Song
             UC Berkeley                         UC Berkeley                         UC Berkeley
       abarth@eecs.berkeley.edu               jww@cs.berkeley.edu              dawnsong@cs.berkeley.edu

                       Abstract                                   a script attempts to access the cookie database, the
                                                                  DOM checks whether the script’s security origin
We identify a class of Web browser implementation                 has sufficient privileges to access the cookies.
vulnerabilities, cross-origin JavaScript capability leaks,      • Object-Capabilities. The JavaScript engine en-
which occur when the browser leaks a JavaScript pointer           forces the same-origin policy using an object-
from one security origin to another. We devise an algo-           capability discipline that prevents one Web site
rithm for detecting these vulnerabilities by monitoring           from obtaining JavaScript pointers to sensitive ob-
the “points-to” relation of the JavaScript heap. Our algo-        jects that belong to a foreign security origin. With-
rithm finds a number of new vulnerabilities in the open-          out JavaScript pointers to sensitive objects in for-
source WebKit browser engine used by Safari. We pro-              eign security origins, malicious scripts are unable
pose an approach to mitigate this class of vulnerabilities        to interfere with those objects.
by adding access control checks to browser JavaScript
engines. These access control checks are backwards-           Most modern Web browsers, including Internet Ex-
compatible because they do not alter semantics of the         plorer, Firefox, Safari, Google Chrome, and Opera, use
Web platform. Through an application of the inline            this design. However, the design’s mismatch in en-
cache, we implement these checks with an overhead of          forcement paradigms leads to vulnerabilities whenever
1–2% on industry-standard benchmarks.                         the browser leaks a JavaScript pointer from one secu-
                                                              rity origin to another. Once a malicious script gets a
1    Introduction                                             JavaScript pointer to an honest JavaScript object, the at-
In this paper, we identify a class of Web browser im-         tacker can leverage the object-capability security model
plementation vulnerabilities, which we refer to as cross-     of the JavaScript engine to escalate its DOM privileges.
origin JavaScript capabilities leaks, and develop sys-        With escalated DOM privileges, the attacker can com-
tematic techniques for detecting, exploiting, and defend-     pletely compromise the honest security origin by inject-
ing against these vulnerabilities. An attacker who ex-        ing a malicious script into the honest security origin.
ploits a cross-origin JavaScript capability leak can in-         To study this class of vulnerabilities, we devise an al-
ject a malicious script into an honest Web site’s secu-       gorithm for detecting individual cross-origin JavaScript
rity origin. These attacks are more severe than cross-        capability leaks. Using this algorithm, we uncover new
site scripting (XSS) attacks because they affect all Web      instances of cross-origin JavaScript capability leaks in
sites, including those free of XSS vulnerabilities. Once      the WebKit browser engine used by Safari. We then il-
an attacker can run script in an arbitrary security origin,   lustrate how an attack can abuse these leaked JavaScript
the attacker can, for example, issue transactions on the      pointers by constructing proof-of-concept exploits. We
user’s bank account, regardless of any SSL encryption,        propose defending against cross-origin JavaScript capa-
cross-site scripting filter, or Web application firewall.     bility leaks by harmonizing the security models used by
   We observe that these cross-origin JavaScript capa-        the DOM and the JavaScript engine.
bility leaks are caused by an architectural flaw shared         • Leak Detection. We design an algorithm for au-
by most modern Web browsers: the Document Object                  tomatically detecting cross-origin JavaScript ca-
Model (DOM) and the JavaScript engine enforce the                 pability leaks by monitoring the “points-to” rela-
same-origin policy using two different security models.           tion among JavaScript objects in the heap. From
The DOM uses an access control model, whereas the                 this relation, we define the security origin of each
JavaScript engine uses object-capabilities.                       JavaScript object by tracing its “prototype chain.”
    • Access Control. The DOM enforces the same-                  We then search the graph for edges that connect ob-
      origin policy using a reference monitor that pre-           jects in one security origin with objects in another
      vents one Web site from accessing resources allo-           security origin. These suspicious edges likely rep-
      cated to another Web site. For example, whenever            resent cross-origin JavaScript capability leaks.
• Vulnerabilities and Exploitation. We implement            leaks as a class of vulnerabilities. Section 3 presents our
    our leak detection algorithm and find two new high-       algorithm for detecting cross-origin JavaScript capabil-
    severity cross-origin JavaScript capability leaks in      ity leaks. Section 4 details the individual vulnerabili-
    WebKit. Although these vulnerabilities are imple-         ties we uncover with our algorithm and outlines tech-
    mentation errors in WebKit, the presence of the           niques for exploiting these vulnerabilities. Section 5
    bugs illustrates the fragility of the general architec-   proposes defending against cross-origin JavaScript ca-
    ture. (Other browsers have historically had similar       pability leaks by adding access control checks to the
    vulnerabilities [17, 18, 19].) We detail these vulner-    JavaScript engine. Section 6 relates our work to the lit-
    abilities and construct proof-of-concept exploits to      erature. Section 7 concludes.
    demonstrate how an attacker can leverage a leaked
    JavaScript pointer to inject a malicious script into      2     JavaScript Capability Leaks
    an honest security origin.                                In this section, we describe our interpretation of
  • Defense. We propose that browser vendors proac-           JavaScript pointers as object-capabilities and identify
    tively defend against cross-origin JavaScript capa-       cross-origin JavaScript capability leaks as a class of im-
    bility leaks by implementing access control checks        plementation vulnerabilities in browsers. We then sketch
    throughout the JavaScript engine instead of reac-         how these vulnerabilities are exploited and the conse-
    tively plugging each leak. Adding access control          quences of a successful exploit.
    checks to the JavaScript engine addresses the root
    cause of these vulnerabilities (the mismatch be-          2.1    Object-Capabilities
    tween the security models used by the DOM and             In modern Web browsers, the JavaScript engine en-
    by the JavaScript engine) and provides defense-in-        forces the browser’s same-origin policy using an object-
    depth in the sense that both an object-capability         capability discipline: a script can obtain pointers only
    and an access control failure are required to create      to JavaScript objects created by documents in its se-
    an exploitable vulnerability. This defense is per-        curity origin. A script can obtain JavaScript point-
    fectly backwards-compatible because these access          ers to JavaScript objects either by accessing prop-
    checks do not alter the semantics of the Web plat-        erties of JavaScript object to which the script al-
    form. Our implementation of these access control          ready has a JavaScript pointer or by conjuring cer-
    checks in WebKit incurs an overhead of only 1–2%          tain built-in objects such as the global object and
    on industry-standard benchmarks.                          Object.prototype [14].              As in other object-
Contributions. We make the following contributions:           capability systems, the ability to influence an object is
                                                              tied to the ability to designate the object. In browsers,
  • We identify a class of Web browser implementa-
                                                              a script can manipulate a JavaScript object only if the
    tion vulnerabilities: cross-origin JavaScript capa-
                                                              script has a pointer to the object. Without a pointer to
    bility leaks. These vulnerabilities arise when the
                                                              an object in a foreign security origin, a malicious script
    browser leaks a JavaScript pointer from one secu-
                                                              cannot influence honest JavaScript objects and cannot
    rity origin to another security origin.
                                                              interfere with honest security origins.
  • We introduce an algorithm for detecting cross-
                                                                 One exception to this object-capability discipline is
    origin JavaScript capability leaks by monitoring the
                                                              the JavaScript global object. According to the HTML 5
    “points-to” relation of the JavaScript heap. Our al-
                                                              specification [10], the global object (also known as the
    gorithm uses a graph-based definition of the secu-
                                                              window object) is visible to foreign security origins.
    rity origin of a JavaScript object.
                                                              There are a number of APIs for obtaining pointers to
  • We reveal cross-origin JavaScript capability leaks
                                                              global objects from foreign security origins. For exam-
    and demonstrate techniques for exploiting these
                                                              ple, the contentWindow property of an 
    vulnerabilities. These exploits rely on the mis-
                                                              element is the global object of the document contained
    match between the DOM’s access control security
                                                              in the frame. Unlike most JavaScript objects, the global
    model and the JavaScript engine’s object-capability
                                                              object is also a DOM object (called window) and is
    security model.
                                                              equipped with a reference monitor that prevents scripts
  • We propose that browsers defend against cross-
                                                              in foreign security origins from getting or setting arbi-
    origin JavaScript capability leaks by implement-
                                                              trary properties of the object. This reference monitor
    ing access control checks in the JavaScript engine.
                                                              does not forbid all accesses because some are desirable.
    This defense is perfectly backwards-compatible
                                                              For example, the postMessage method [10] is ex-
    and achieves a low overhead of 1–2%.
                                                              posed across origins to facilitate mashups [1]. These
Organization. This paper is organized as follows.             exposed properties complicate the enforcement of the
Section 2 identifies cross-origin JavaScript capability       same-origin policy, which can lead to vulnerabilities.
2.2   Capability Leaks                                          Most Web sites contains innumerable laundries. We
Browsers occasionally contain bugs that leak JavaScript      illustrate how an attacker can abuse a laundry by ex-
pointers from one security origin to another. These          amining a representative laundry from the Prototype
vulnerabilities are easy for developers to introduce         JavaScript library [22]: invoke. The invoke method
into browsers because the DOM contains pointers to           is used to call a method, specified by name, on each
JavaScript objects in multiple security origins and de-      object contained in an array. The attacker can use this
velopers can easily select the wrong pointer to disclose     function to trick the honest page into calling a univer-
to a script. We identify these vulnerabilities as a class,   sal DOM method, such as setTimeout. Suppose
which we call cross-origin JavaScript capabilities leaks,    the attacker has a JavaScript pointer to an array named
because they follow a common pattern. Identifying this       honest_array from an honest document that uses
class lets us analyze the concepts common to these vul-      the Prototype library (for how this might occur, see Sec-
nerabilities in all browsers.                                tion 4.3) and that honest_window is the honest docu-
                                                             ment’s global object. The attacker can inject a malicious
   The JavaScript language makes pointer leaks particu-
                                                             script into the honest security origin as follows:
larly devastating for security because JavaScript objects
inherit many of their properties from a prototype ob-        honest_array.push(honest_window);
ject. When a script accesses a property of an object, the    honest_array.invoke("setTimeout",
JavaScript engine uses the following algorithm to look           "... malicious script ...", 0);
up the property:
                                                             The attacker first adds the honest_window object
  • If the object has the property, return its value.
                                                             to the array and then asks the honest principal to call
  • Otherwise, look up the property on the ob-
                                                             the setTimeout method of the honest_window.
    ject’s prototype (designated by the current object’s
                                                             When the JavaScript engine attempts to call the
    __proto__ property).
                                                             setTimeout DOM API, the DOM permits the call be-
These prototype objects, in turn, inherit many of            cause the honest invoke method (acting as a confused
their properties from their prototypes in a chain that       deputy) issued the call. The DOM then runs the mali-
leads back to the Object.prototype object, whose             cious script supplied by the attacker in the honest secu-
__proto__ property is null. All the objects associ-          rity origin.
ated with a given document have a prototype chain that
leads back to that document’s Object.prototype               2.4    Consequences
object. Given a JavaScript pointer to an object, a script    Once the attacker is able to run a malicious script in the
can traverse this prototype chain by accessing the ob-       honest security origin, all the browser’s cross-origin se-
ject’s __proto__ property. In particular, if an at-          curity protections evaporate. The situation is as if every
tacker obtains a pointer to an honest object, the at-        Web site contained a cross-site scripting vulnerability:
tacker can obtain a pointer to the honest document’s         the attacker can steal the user’s authentication cookie or
Object.prototype object and can influence the be-            password, learn confidential information present on the
havior of all the other JavaScript objects associated with   Web site (e.g., read email messages on a webmail site),
the honest document.                                         and issue transactions on behalf of the user (e.g., trans-
                                                             fer money out of the user’s bank account). Because these
2.3   Laundries                                              cross-origin JavaScript capability leaks are browser vul-
Once the attacker has obtained a pointer to the              nerabilities, there is little a Web site can do to defend
Object.prototype of an honest document, the at-              itself against these attacks.
tacker has several avenues for compromising the hon-
est security origin. One approach is to abuse pow-           3     JavaScript Capability Leak Detection
erful functions reachable from Object.prototype,             In this section, we describe the design and implementa-
which we refer to as laundries because they let the at-      tion of an algorithm for detecting cross-origin JavaScript
tacker “wash away” his or her agency (analogous to           capability leaks. Although the algorithm has a modest
laundering money). These functions often call one or         overhead, our instrumented browser performs compara-
more DOM APIs, letting the attacker call these APIs in-      bly to Safari 3.1, letting us analyze complex Web appli-
directly. Because these functions are defined by the hon-    cations.
est document, the DOM’s reference monitor allows the
access [10]. However, if the attacker calls these func-      3.1    Design
tions with unexpected arguments, the functions might         Assigning Security Origins. To detect cross-origin
become confused deputies [9] and inadvertently perform       JavaScript capability leaks, we monitor the heap graph,
the attacker’s misdeeds.                                     the “points-to” relation between JavaScript objects in the
JavaScript heap (see Section 3.2 for details about the        3.2    The “Points-To” Relation
“points-to” relation). We annotate each JavaScript ob-        In our heap graph, we include two kinds of points in
ject in the heap graph with a security origin indicating      the “points-to” relation: explicit pointers that are stored
which security origin “owns” the object. We compute           as properties of JavaScript objects and implicit pointers
the security origin of each object directly from the “is-     that are stored internally by the JavaScript engine.
prototype-of” relation in the heap graph using the fol-
lowing algorithm:                                             Explicit Pointers. A script can alter the properties of
                                                              an object using the get, set, and delete operations.
 1. Let obj be the JavaScript object in question.
 2. If obj was created with a non-null prototype, as-           • get looks up the value of an object property.
    sign obj the same origin as its prototype.                  • set alters the value of an object property.
 3. Otherwise, obj must be the object prototype for             • delete removes a property from an object.
    some document d. In that case, assign obj the se-         To monitor the “points-to” relation between JavaScript
    curity origin of d (i.e., the scheme, host, and port of   objects in the JavaScript heap, we instrument the set
    that d’s URL).                                            operation. Whenever the JavaScript engine invokes the
                                                              set operation to store a JavaScript object in a prop-
This algorithm is unambiguous because, when created,
                                                              erty of another JavaScript object, we add an edge be-
each JavaScript object has a unique prototype, identi-
                                                              tween the two objects in our representation of the heap
fied by its __proto__ property. Although an object’s
                                                              graph. If the set operation overwrites an existing prop-
__proto__ can change over time, we fix the security
                                                              erty, we remove the obsolete edge from the graph. To
origin of an object at creation-time.
                                                              improve performance, we ignore JavaScript values be-
Minimal Capabilities. This algorithm for assigning            cause JavaScript values cannot hold JavaScript pointers
security origins to objects is well-suited to analyzing       and therefore are leaves in the heap graph. We remove
leaks of JavaScript pointers for two reasons. First,          JavaScript objects from the heap graph when the objects
the algorithm is defined largely without reference to         are deleted by the JavaScript garbage collector.
the DOM, letting us catch bugs in the DOM. Second,            Implicit Pointers. The above instrumentation does
the algorithm reflects an object-capability perspective       not give us a complete picture of the “points-to” relation
in that each JavaScript object is a strictly more pow-        in the JavaScript heap because the operational seman-
erful object-capability than the Object.prototype             tics of the JavaScript language [14] rely on a number of
object that terminates its prototype chain. An attacker       implicit JavaScript pointers, which are not represented
with a JavaScript pointer to the object can follow the        explicitly as properties of a JavaScript object. For exam-
object’s prototype chain by repeatedly dereferencing the      ple, consider the following script:
object’s __proto__ property and eventually obtain a
JavaScript pointer to the Object.prototype object.            var x = ...
In these terms, we view the Object.prototype ob-              function f() {
ject as the “minimal object-capability” of an origin.           var y = ...
                                                                function g() {
Suspicious Edges. After annotating the heap graph                 var z = ...
with the security origin of each object, we detect a              function h() { ... }
leaked JavaScript pointer as an edge from an object in          }
one security origin to an object in another security ori-     }
gin. These suspicious edges represent failures of the
JavaScript engine to segregate JavaScript objects into        Function h can obtain the JavaScript pointers stored in
distinct security origins. Not all of these suspicious        variables x, y, and z even though there are no JavaScript
edges are actually security vulnerabilities because the       pointers between h and these objects. The function h
HTML specification requires some JavaScript objects,          can obtain these JavaScript pointers because the algo-
such as the global object, be visible to foreign security     rithm for resolving variable names makes use of an im-
origins. To prevent exploits, browsers equip these ob-        plicit “next” pointer that connects h’s scope object to
jects with a reference monitor that prevents foreign se-      the scope objects of g, f, and the global scope. Instead
curity origins from getting or setting arbitrary properties   of being stored as properties of JavaScript objects, these
of the object. In addition to the global object, a hand-      implicit pointers are stored as member variables of na-
ful of other JavaScript objects required to be visible to     tive objects in the JavaScript engine. To improve the
foreign security origins. These objects are annotated in      completeness of our heap graph, we include these im-
WebKit’s Interface Description Language (IDL) with the        plicit JavaScript pointers explicitly as edges between the
attribute DoNotCheckDomainSecurity.                           JavaScript scope objects.
Global Object - 1c700040

                                                                                                                                                                                                                                                                                                                                                                                                                                                                     @SCOPECHAIN GLOBAL                 window      window Math               Math document    local - document         document                                                                                                                                                                                                               decodeURI                                                               encodeURIComponent                                   isNaN                                                                  NaN     NaN      undefined undefined   Infinity Infinity

                                                                                                                                                                                                                                                                                                                                                                                                                                        __proto__              Window Shell - 1c700000                              object - 1c700f60                object - 1c701340                                                                                                                                                                                                                                                                decodeURIComponent                                                            escape                                          kjsprint        parseFloat                           1c710090             a           1c7100a0

                                                                                                                                                                                                                                                                                                                                                                                                                                  __proto__                                                                                       __proto__                                    RangeError                                                                                                          EvalError          URIError       TypeError      ReferenceError     SyntaxError                              object - 1c701140                                 dumpHeap              object - 1c701200                    eval            object - 1c701040                                          parseInt

                                                                                                                                                   Date                                                                                               Number                       Boolean                                                                                                     Array             object - 1c700020                           object - 1c701320                                                                                                                                                     String                Error                                                                                                                                        RegExp                                                                    encodeURI                                              isFinite              object - 1c701280                                     unescape

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        __proto__                                                                                                                                                                                                                                                                                                                                                      object - 1c701180                                                object - 1c7010c0                                                    object - 1c701000

                                                                                                                                                                                                                                                                                                                                                                                                                                                            object - 1c701300                                                    object - 1c700e20                                                                            object - 1c700de0                       object - 1c700f20               object - 1c700ee0                   object - 1c700e60                  object - 1c700ea0

                                                                                                                                                                                                                                                                                                                                     Object                                                                                                __proto__                 __proto__                                                    prototype constructor                                                       constructor      prototype          prototype        constructor            prototype     constructor                 constructor    prototype             prototype constructor                                                         object - 1c701240                                       object - 1c700f80                                                        object - 1c700fc0

                                                                  object - 1c700c60                                                                               object - 1c700c20                                                                      object - 1c700be0                                                                                                  object - 1c700b20                               __proto__                   object - 1c7012e0                     object - 1c700b60                  object - 1c7008c0               object - 1c700da0                      object - 1c700860                         object - 1c700a40                       object - 1c7009e0                        object - 1c700920                     object - 1c700980                       object - 1c700d60

Function                                  now       parse                 UTC                                       constructor      constructor           prototype         prototype                                                                     constructor prototype                                                                                                prototype      constructor                                                       __proto__                          prototype    constructor                            fromCharCode            __proto__          constructor    prototype     __proto__              __proto__             __proto__           __proto__                                          __proto__                                    prototype         constructor           __proto__                 object - 1c7011c0            __proto__               object - 1c701080           __proto__                                            object - 1c701100

                                                                                                                 number prototype - 1c7004e0                       date prototype - 1c700680                                                        boolean prototype - 1c700440                                                                                               array prototype - 1c700400                                               object - 1c7012c0                       string prototype - 1c700420                                                                                        error prototype - 1c7007c0                                                                                                                                regExp prototype - 1c7006a0                                              __proto__                                         __proto__                                                __proto__      __proto__

       object - 1c700d20        object - 1c700ca0                 object - 1c700ce0                valueOf   toExponential     toFixed    toLocaleString       toPrecision         toString                            __proto__        __proto__        toString valueOf                                                                                     __proto__                                       __proto__                                  __proto__                     __proto__           __proto__                                          object - 1c700ba0                                   __proto__                 toString                 __proto__    __proto__    __proto__              __proto__             __proto__     __proto__    exec           test toString             compile                                             __proto__                                         __proto__                                                                  __proto__

                                                      __proto__                object - 1c700580                                                                             object - 1c700500        __proto__   __proto__                                                                                                      __proto__                                                                   object prototype - 1c7000a0                                                                                                                                             __proto__                                 __proto__                                                                       object - 1c700700                  object - 1c700740               object - 1c700780               object - 1c7006c0       __proto__                             __proto__                                           __proto__                                                                  __proto__

                           __proto__    __proto__            __proto__         object - 1c700600             object - 1c7005c0             object - 1c700540                 object - 1c700640                      object - 1c700460                   object - 1c7004a0                       toLocaleString               toString         valueOf    prototype               constructor           __defineGetter__ __defineSetter__               __lookupGetter__             __lookupSetter__                 hasOwnProperty                  isPrototypeOf           propertyIsEnumerable                     __proto__              object - 1c700820

                                                                                __proto__                          __proto__              __proto__         __proto__ __proto__           __proto__                 __proto__   __proto__               object - 1c700100          object - 1c7000c0             object - 1c700140            object - 1c700aa0              object - 1c700240                   object - 1c700280                  object - 1c7002c0               object - 1c700300                  object - 1c700180               object - 1c700200                   object - 1c7001c0                                             __proto__                                               __proto__             __proto__                 __proto__                   __proto__

                                                                                                                                                                                                                                                                                                                 __proto__                                        __proto__ __proto__                           __proto__                                  __proto__                               __proto__                   __proto__          __proto__           __proto__              __proto__        __proto__

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           function prototype - 1c700060

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          __proto__      prototype        constructor     apply    __proto__       call __proto__            toString    __proto__

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     object - 1c700ae0                      object - 1c700380                   object - 1c7003c0                    object - 1c700340

                                                                                                                                                                                                                                                                                        Figure 1: The heap graph of an empty document.

3.3                                             Implementation
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Attacker Global Object@0x1a9e1420                                                                                                                                                                                                                  Victim Global Object@0x1a9e2940
We implemented our leak detection algorithm in a 1,393                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              document                                                                            document                                                             Object

line patch to WebKit’s Nitro JavaScript engine. Our al-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      object@0x1a9e3c20

gorithm can construct heap graphs of complex Web ap-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             __proto__                                                           object@0x1a9e3380

plications, such as Gmail or the Apple Store. For exam-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          object@0x1a9e3c00

ple, one heap graph of a Gmail inbox contains 54,140                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  __proto__

nodes and 130,995 edges. These graphs are often vi-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               object@0x1a9e3be0

sually complex and difficult to interpret manually. Fig-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               __proto__                                                                                            prototype

ure 1 illustrates the nature of these graphs by depicting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         object@0x1a9e3bc0

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       __proto__
the heap graph of an empty document. Although our in-
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   object@0x1a9e3ba0
strumentation slows down the browser, the instrumented                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       __proto__
browser is still faster than Safari 3.1, demonstrating that                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Object Prototype@0x1a9e2980

our algorithm scales to complex Web applications.

4                           Vulnerabilities and Exploitation                                                                                                                                                                                                                                                                                                                                                                                                                                                                               Figure 2: Selected nodes from a heap graph showing a
In this section, we use our leak detector to detect cross-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 cross-origin JavaScript capability leak of the document
origin JavaScript capability leaks in WebKit. After                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        object, object@0x1a9e3c20, after a navigation.
discovering two new vulnerabilities, we illuminate the
vulnerabilities by constructing proof-of-concept exploits
using three different techniques. In addition, we apply                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The layoutTestController contains a number of
our understanding of JavaScript pointers to breaking the                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   objects that are shared between all security origins. Our
Subspace [11] mashup design.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               instrumentation flags JavaScript pointers to these objects
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           as suspicious, and, in fact, these pointers are exploitable
4.1                                             Test Suite                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 in the test configuration of the browser. However, these
To find example cross-origin JavaScript capability leaks,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  pointers are not present in the release configuration of
we run our instrumented browser through a test suite.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      the browser because the layoutTestController
Ideally, to reduce the number of false negatives, we                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       itself is present only during testing. We white listed
would use a test suite with high coverage. Because our                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     these objects as visible to multiple security origins.
goal is to find example vulnerabilities, we use the We-
bKit project’s regression test suite. This test suite exer-
cises a variety of browser security features and tests for                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 4.2                                                                Navigation and Document
the non-existence of past security vulnerabilities. Using
this test suite, our instrumentation found two new high-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Vulnerability. When the browser navigates a window
severity cross-origin JavaScript capability leaks. Instead                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 from one Web page to another, the browser replaces the
of attempting to discover and patch all these leaks, we                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    document originally displayed in the window with a new
recommend a more comprehensive defense, detailed in                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        document retrieved from the network. Our instrumen-
Section 5.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 tation found that WebKit leaks a JavaScript pointer to
   WebKit’s regression test suite uses a JavaScript ob-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    the new document object every time a window navi-
ject named layoutTestController to facilitate its                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          gates because the DOM updates the document prop-
tests. For example, each tests notifies the testing harness                                                                                                                                                                                                                                                                                                                                                                                                                                                                                erty of the old global object to point to the new doc-
that the test is complete by calling the notifyDone                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ument occupying the frame. This leak is visible in
method of the layoutTestController. We mod-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                the heap graph (see Figure 2) as a dashed line from
ified this notifyDone method to store the JavaScript                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       Attacker Global Object@0x1a9e1420 to the
heap graph in the file system after each test completes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   honest document object, object@0x1a9e3c20.
Exploit. Crafting an exploit for this vulnerability is
                                                                     Attacker Global Object@0x1c1d0040                       Victim Global Object@0x1c1d13e0
subtle. An attacker cannot simply hold a JavaScript
                                                                                      location                                     location    Object
pointer to the old global object and access its                             object@0x1c1d2720                object@0x1c1d2740
document property because all JavaScript pointers to
                                                                                                         __proto__   __proto__          object@0x1c1d1e20
global objects are updated to the new global object when
                                                                                                          object@0x1c1d2700                    prototype
a frame is navigated navigation [10]. However, the prop-                                                                         __proto__
erties of the old global object are still visible to func-                                                             Object Prototype@0x1c1d1420

tions defined by the old document via the scope chain
as global variables. In particular, an attacker can exploit
this vulnerability as follows:                                Figure 3: Selected nodes from a heap graph showing
 1. Create an  to http://attacker.                    a cross-origin JavaScript capability leak of the location
    com/iframe.html, which defines the following              prototype, object@0x1c1d2700, to the attacker af-
    function in a malicious document:                         ter the victim attempts to frame bust.
      function exploit() {
        var elmt = document.                                  This line of JavaScript changes the location of the top-
            createElement("script");                          most frame, navigating that frame to a trusted Web site.
        elmt.src =                                            The browser permits cross-origin access to a frame’s
            "http://attacker.com/atk.js";                     location object to allow navigation [1]. If this script
        document.body.appendChild(elmt);                      is the first script to access the location object of the
      }                                                       top frame, then WebKit will mistakenly connect the
                                                              top frame’s newly constructed location object to the
    Notice that the exploit function refers to
                                                              Object.prototype of the child frame (instead of
    the document as a global variable, document,
                                                              to the Object.prototype of the top frame) because
    and not as a property of the global object,
                                                              the child frame is currently in scope lexically.
    window.document.
 2. In the parent frame, store a pointer to the exploit       Exploit. To exploit this cross-origin JavaScript capa-
    function by running the following JavaScript:             bility leak, the attacker proceeds in two phases: (1)
      window.f = frames[0].exploit;                           the attacker obtains a JavaScript pointer to the hon-
                                                              est Object.prototype, and (2) the attacker abuses
 3. Navigate the frame to http://example.com/.                the honest Object.prototype to inject a malicious
 4. Call the function: window.f().                            script into the honest security origin. To obtain a
After the attacker navigates the child frame to http://       JavaScript pointer to the honest Object.prototype,
example.com/, the DOM changes the document                    the attacker create an  to an honest document
variable in the function exploit to point to the honest       that frame busts and runs the following script in response
document object instead of the attacker’s document ob-        to the beforeunload event:
ject. The exploit function can inject arbitrary script
into the honest document using a number of standard           var location_prototype =
DOM APIs. Once the attacker has injected script into              window.location.__proto__;
the honest document, the attacker can impersonate the         var honest_object_prototype =
honest security origin to the browser.                            location_prototype.__proto__;

4.3    Lazy Location and History                              Because the beforeunload event handler runs af-
                                                              ter the child frame has attempted to frame bust, the at-
Vulnerability. For performance, WebKit instantiates           tacker’s location object has been instantiated by the hon-
the window.location and window.history ob-                    est document and is mistakenly attached to the honest
jects lazily the first time they are accessed. When instan-   Object.prototype (see Figure 3). The attacker ob-
tiating these objects, the browser constructs their proto-    tains a pointer to the honest Object.prototype by
type chains. In some situations, WebKit constructs an         traversing this prototype chain.
incorrect prototype chain that connects these objects to         Once the attacker has obtained a JavaScript pointer
the Object.prototype of a foreign security origin,            to the honest Object.prototype, there are a num-
creating a vulnerability if, for example, a document uses     ber of techniques the attacker can use to compromise the
the following script to “frame bust” [12] in order to avoid   honest security origin completely. We describe two rep-
clickjacking [7] attacks:                                     resentative examples:
top.location.href =                                            1. Many Web sites use JavaScript libraries to smooth
    "http://example.com/";                                        over incompatibilities between browsers and reuse
common code. One of the more popular JavaScript                 The JavaScript engine will call the attacker’s setter
   libraries is the Prototype library [22], which is used          function instead of storing honest_dom_node
   by CNN, Apple, Yelp, Digg, Twitter, and many oth-               into the foo property of obj, causing the
   ers. If the honest page uses the Prototype library,             variable x to contain a JavaScript pointer to
   the attacker can inject arbitrary script into the hon-          honest_dom_node. Once the attacker’s func-
   est page by abusing the powerful invoke function                tion is called with a pointer to the honest DOM
   defined by the Prototype library. For example, the              node, the attacker can inject malicious script into
   attacker can use the follow script:                             the honest document using the innerHTML API.
   var honest_function =                                     4.4    Capability Leaks in Subspace
       honest_object_prototype.
       __defineGetter__;                                     The Subspace mashup design [11] lets a trusted integra-
   var honest_array =                                        tor communicate with an untrusted gadget by passing a
       honest_function.                                      JavaScript pointer from the integrator to the gadget:
       argumentNames();                                            A Subspace JavaScript object is created in
   honest_array.push(frames[0]);                                   the top frame and passed to the mediator
   honest_array.invoke("setTimeout",                               frame... The mediator frame still has access to
       "... malicious script ...");                                the Subspace object it obtained from the top
   In the Prototype library, arrays contain a method               frame, and passes this object to the untrusted
   named invoke that calls the method named                        frame. [11]
   by its first argument on each element of its ar-
   ray, passing the remaining arguments to the in-           Unfortunately, the Subspace design relies on leaking
   voked method. To abuse this method, the at-               a JavaScript pointer from a trusted security origin to
   tacker first obtains a pointer to an honest ar-           an untrusted security origin, creating a cross-origin
   ray object by calling the argumentNames                   JavaScript capability leak. By leaking the communica-
   method of an honest function reachable from               tion object, Subspace also leaks a pointer to the trusted
   the honest_object_prototype object. The                   Object.prototype via the prototype chain of the
   attacker then pushes the global object of the             communication object.
   child frame onto the array and calls the honest              To verify this attack, we examined CrossSafe [25], a
   document’s setTimeout method via invoke.                  public implementation of Subspace. We ran a Cross-
   The honest global object has a reference mon-             Safe tutorial in our instrumented browser and examined
   itor that prevents the attacker from accessing            the resulting heap graph. Our detector found a cross-
   setTimeout directly, but the reference monitor            origin JavaScript capability leak: the channel object
   allows invoke to access setTimeout because                is leaked from the integrator to the gadget. By repeat-
   invoke is defined by the honest document.                 edly dereferencing the __proto__ property, the un-
2. Even if the honest Web page does not use a complex        trusted gadget can obtain a JavaScript pointer to the
   JavaScript library, the attacker can often find a snip-   trusted Object.prototype object. The untrusted
   pet of honest script to trick. For example, suppose       gadget can then inject a malicious script into the trusted
   the attacker installs a “setter” function for the foo     integrator using one of the techniques described in Sec-
   property of the honest Object.prototype as                tion 4.3.
   follows:
                                                             5     Defense
   function evil(x) {
                                                             In this section, we propose a principled defense for
     x.innerHTML =
                                                             cross-origin JavaScript capability leaks. Our defense ad-
         ’’;
                                                             a minor performance overhead.
   });
   honest_object_prototype.                                  5.1    Approach
       __defineSetter__(’foo’, evil);
                                                             Currently, browser vendors defend against cross-origin
   Now, if the honest script stores a DOM node in a          JavaScript capability leaks by patching each individual
   property of an object as follows:                         leak after the leak is discovered. We recommend an-
   var obj = new Object();                                   other approach for defending against these vulnerabili-
   obj.foo = honest_dom_node;                                ties: add access control checks throughout the JavaScript
                                                             engine. We recommend this principled approach over
                                                             ad-hoc leak plugging for two reasons:
• This approach addresses the core design issue un-         Although we recommend that browsers adopt the access
    derlying cross-origin JavaScript capability leak vul-     control paradigm for Web content, other projects, such
    nerabilities: the mismatch between the DOM’s ac-          as Caja [16] and ADsafe [3], take the opposite approach
    cess control security model and the JavaScript en-        and elect to enforce an object-capability discipline on
    gine’s object-capability security model.                  the DOM. These projects succeed with this approach be-
  • This approach provides a second layer of defense:         cause the preceding considerations do not apply: these
    if the browser is leak-free, all the access con-          projects target new code (freeing themselves from back-
    trol checks will be redundant and pass, but if the        wards compatibility constraints) that is written in a sub-
    browser contains a leak, the access control checks        set of JavaScript (freeing themselves from problematic
    prevent the attacker from exploiting the leak.            language features). For further discussion, see Section 6.
In a correctly implemented browser, Web content will be       5.2   Design
unable to determine whether the browser implements the
access control checks we recommend. The additional            We propose adding access control checks to the
access control checks enhance the mechanism used to           JavaScript engine by inserting a reference monitor into
enforce the same-origin policy but do not alter the policy    each JavaScript object. The reference monitor interposes
itself, resulting in zero compatibility impact.               on each get and set operation (described in Section 3)
                                                              and performs the following access control check:
   Another plausible approach to mitigating these vul-
nerabilities is to adopt an object-capability discipline       1. Let the active origin be the origin of the document
throughout the DOM. This approach mitigates the sever-            that defined the currently executing script.
ity of cross-origin JavaScript capability leaks by limiting    2. Let the target origin be the origin that “owns” the
the damage an attacker can wreak with the leaked capa-            JavaScript object being accessed, as computed by
bility. For example, if the browser leaks an honest his-          the algorithm in Section 3.1.
tory object to the attacker, the attacker would be able to     3. Allow the access if the browser considers the active
manipulate the history object, but would not be able to           origin and the target origin to be the same origin
alter the document object. Conceptually, either adding            (i.e., if their scheme, hosts, and ports match).
access control checks to the JavaScript engine or adopt-       4. Otherwise, deny access.
ing an object-capability discipline throughout the DOM        If the access is denied, the JavaScript engine returns the
resolves the underlying architectural security issue, but     value undefined for get operations and simply ig-
we recommend adopting the access control paradigm for         nores set operations. In addition to adding these ac-
two main reasons:                                             cess control checks, we record the security origin of each
  • Adopting an object-capability discipline through-         JavaScript object when the object is created. Our imple-
    out the DOM requires “taming” [15] the DOM API.           mentation does not currently insert access control checks
    The current DOM API imbues every DOM node                 for delete operations, but these checks could be added
    with the full authority of the node’s security origin     at a minor performance cost. Some JavaScript objects,
    because the API exposes a number of “universal”           such as the global object, are visible across origins. For
    methods, such as innerHTML that can be used               these objects, our reference monitor defers to the refer-
    to run arbitrary script. Other researchers have de-       ence monitors that already protect these objects.
    signed capability-based DOM APIs [4], but taming
                                                              5.3   Inline Cache
    the DOM API requires a number of non-backwards
    compatible changes. A browser that makes these            The main disadvantage of performing an access control
    changes will be unpopular because the browser will        check for every JavaScript property access is the run-
    be unable to display a large fraction of Web sites.       time overhead of performing the checks. Sophisticated
  • The JavaScript language itself has a number of fea-       Web applications access JavaScript properties an enor-
    tures that make enforcing an object-capability dis-       mous number of times per second, and browser vendors
    cipline challenging. For example, every JavaScript        have heavily optimized these code paths. However, we
    object has a prototype chain that eventually leads        observe that the proposed access checks are largely re-
    back to the Object.prototype, making it dif-              dundant and amenable to optimization because scripts
    ficult to create a weaker object-capability than          virtually always access objects from the same origin.
    the Object.prototype. Unfortunately, the                     Cutting-edge JavaScript engines, including Sa-
    Object.prototype itself represents a power-               fari 4’s Nitro JavaScript Engine, Google Chrome’s
    ful object-capability with the ability to interfere       V8 JavaScript engine, Firefox 3.5’s TraceMonkey
    with the properties of every other object from the        JavaScript engine, and Opera 11’s Carakan JavaScript
    same document (e.g., the exploit in Section 4.3.)         engine, optimize JavaScript property accesses using an
3.0%
inline cache [24]. (Of the major browser vendors, only
Microsoft has yet to announce plans to implement this                      2.5%
optimization.) These JavaScript engines group together
JavaScript objects with the same “structure” (i.e., whose                  2.0%

                                                                Slowdown
properties are laid out the same order in memory). When                    1.5%
a script accesses a property of an object, the engine
caches the object’s group and the memory offset of the                     1.0%

property inline in the compiled script. The next time
                                                                           0.5%
that compiled script accesses a property of an object, the
inline cache checks whether the current object has the                     0.0%
                                                                                  Dromaeo              SunSpider            V8 Suite
same structure as the original object. If the two objects
                                                                                                   Benchmark
have the same structure, a cache hit, the engine uses the
memory offset stored in the cache to access the prop-
                                                               Figure 4: Overhead for access control checks as measure
erty. Otherwise, a cache miss, the engine accesses the
                                                               by industry-standard JavaScript benchmarks (average of
property using the normal algorithm.
                                                               10 runs, 95% confidence).
   Notice that two objects share the same structure only
if their prototypes share the same structure. Addi-
tionally, the Nitro JavaScript engine initializes each                     12%

Object.prototype with a unique structure identi-
                                                                           10%
fier, preventing two object from different security ori-
gins (as defined by our prototype-based algorithm) from                     8%

being be grouped together as sharing the same structure.
                                                                Slowdown

                                                                            6%
(Other JavaScript engines, such as V8, do contain struc-
ture groups that span security origins, but this design                     4%

is not necessary for performance.) Whenever the inline                      2%
cache has a hit, we observe the following:
                                                                            0%
  • The current object is from the same security origin                            Read      Write                 Read       Write

    as the original object that created the cache entry                    -2%
                                                                                    Inline Cache                   No Inline Cache
    because the two objects share the same structure.
  • The script has the same security origin as when the        Figure 5: Overhead for reading and writing properties of
    cache entry was created because the cache is inlined       JavaScript objects both with and without an inline cache
    into the script and the security origin of the script is   as measured by microbenchmarks (average of 10 runs,
    fixed at compile time.                                     95% confidence).
Taken together, these properties imply that the current
access control check will return the same result as the
original check because both of the origins involved in the     by computing the currently active origin from the lexical
check are unchanged. Therefore, we need not perform            scope, which can be reduced with further engineering.
an access control check during a cache hit, greatly reduc-
ing the performance overhead of adding access control
                                                               Overall Performance. Our implementation incurs a
checks to the JavaScript engine.
                                                               small overhead on industry-standard JavaScript bench-
                                                               marks (see Figure 4). On Mozilla’s Dromaeo bench-
5.4   Evaluation
                                                               mark, we observed a 0.57% slowdown for access con-
To evaluate performance overhead of our defense,               trol versus an unmodified browser (average of 10 runs,
we added access control checks to Safari 4’s Nitro             ±0.58%, 95% confidence). On Apple’s SunSpider
JavaScript engine in a 394 line patch. We verified that        benchmark, we observed a 1.16% slowdown (average
our access control checks actually defeat the proof-of-        of 10 runs, ±0.45%, 95% confidence). On Google’s V8
concept exploits we construct in Section 4. To speed up        benchmark, we observed a 1.94% slowdown (average of
the access control checks, we represented each security        10 runs, ±0.61, 95% confidence). We hypothesize that
origin by a pointer, letting us allow the vast majority of     the variation in slowdown between these benchmarks is
accesses using a simple pointer comparison. In some            due to the differing balance between arithmetic opera-
rare cases, including to deny access, our implementation       tions and property accesses in the different benchmarks.
performs a more involved access check. The majority of         Note that these overhead numbers are tiny in comparison
performance overhead in our implementation is caused           with the 338% speedup of Safari 4 over Safari 3.1 [24].
Benefits of Inline Cache. We attribute much of the           browsers. We face the opposite constraints: we cannot
performance of our access checks to the inline cache,        alter legacy content but we can change the browser. For
which lets our implementation skip redundant access          these reasons, we recommend the opposite design point.
control checks for repeated property accesses. To evalu-
ate the performance benefits of the inline cache, we cre-    Opus Palladianum. The Opus Palladianum (OP) Web
ated two microbenchmarks, “read” and “write.” In the         browser [6] isolates security origins into separate sand-
read benchmark, we repeatedly performed a get opera-         boxed components. This component-based browser
tion on one property of a JavaScript object in a loop. In    architecture makes it easier to reason about cross-
the write benchmark, we repeatedly performed a set           origin JavaScript capability leaks because these capa-
operation on one property of a JavaScript object in a        bility leaks must occur between browser components
loop. We then measured the slowdown incurred by the          instead of within a single JavaScript heap. We can
access control checks both with the inline cache enabled     view the sandbox as a coarse-grained reference mon-
and with the inline cache disabled (see Figure 5). With      itor. Unfortunately, the sandbox alone is too coarse-
the inline cache enabled, we observed a −0.08% slow-         grained to implement standard browser features such
down (average of 50 runs, ±0.22%, 95% confidence)            as postMessage. To support these features, the
on the read benchmark and a 0.55% slowdown (aver-            OP browser must allow inter-component references, but
age of 50 runs, ±0.74%, 95% confidence) on the write         without a public implementation, we are unable to eval-
benchmark. By contrast, with the inline cache disabled,      uate whether these inter-component references give rise
we observed a 9.41% slowdown (average of 50 runs,            to cross-origin JavaScript capability leaks.
±1.11%, 95% confidence) on the read benchmark and
a 10.25% slowdown (average of 50 runs, ±1.00%, 95%           Script Accenting. Script accenting [2] is a technique
confidence) on the write benchmark.                          for adding defense-in-depth to the browser’s enforce-
   From these observations we conclude that browser          ment of the same-origin policy. To mitigate mistaken
vendors can implement access control checks for ev-          script execution, the browser encrypts script source code
ery get and set operation with a performance over-           with a key specific to the security origin of the script.
head of less than 1–2%. To reap these security bene-         Whenever the browser attempts to run a script in a secu-
fits with minimal overhead, the JavaScript engine should     rity origin, the browser first decrypts the script with the
employ an inline cache to optimize repeated property         security origin’s key. If decryption fails, likely because
accesses, and the inline cache should group structurally     of a vulnerability, the browser refuses to execute the
similar JavaScript objects only if those objects are from    script. Script accenting similarly encrypts the names of
the same security origin.                                    JavaScript properties ostensibly preventing a script from
                                                             manipulating properties of objects from another origin.
6   Related Work                                             Unfortunately, this approach is not expressive enough to
                                                             represent the same-origin policy (e.g., this design does
The operating system literature has a rich history
                                                             not support document.domain). In addition, script
of work on access control and object-capability sys-
                                                             accenting requires XOR encryption to achieve sufficient
tems [13, 21, 23, 8]. In this section, we focus on com-
                                                             performance, but XOR encryption lacks the integrity
paring our work to related work on access control and
                                                             protection required to make the scheme secure.
object-capability systems in Web browsers.
FBJS, Caja, and ADsafe. Facebook, Yahoo!, and                Cross-Origin Wrappers. Firefox 3 uses cross-origin
Google have developed JavaScript subsets, called             wrappers [20] to mitigate security vulnerabilities caused
FBJS [5], ADsafe [3], and Caja [16], respectively,           by cross-origin JavaScript capability leaks. Instead of
that enforce an object-capability discipline by remov-       exposing JavaScript objects directly to foreign security
ing problematic JavaScript features (such as prototypes)     origins, Firefox exposes a “wrapper” object that me-
and DOM APIs (such as innerHTML). These projects             diates access to the wrapped object with a reference
take the opposite approach from this paper: they extend      monitor. Implementing cross-origin wrappers correctly
the JavaScript engine’s object-capability security model     is significantly more complex than implementing ac-
to the DOM instead of extending the DOM’s access             cess control correctly because the cross-origin wrappers
control security model to the JavaScript engine. These       must wrap and unwrap objects at the appropriate times
projects choose this alternative design point for two rea-   in addition to implementing all the same access con-
sons: (1) the projects target new social networking gad-     trol checks. Our access control design can be viewed
gets and advertisements that are free from compatibil-       as a high-performance technique for reducing this com-
ity constraints and (2) these projects are unable to al-     plexity (and the attendant bugs) by adding the reference
ter legacy browsers because they must work in existing       monitor to every object.
7   Conclusions                                                  [4] Douglas Crockford. ADsafe DOM API.
In this paper, we identify a class of vulnerabilities, cross-    [5] Facebook. Facebook Markup Language (FBML).
origin JavaScript capability leaks, that arise when the          [6] Chris Grier, Shuo Tang, and Samuel T. King. Se-
browser leaks a JavaScript pointer from one security                 cure web browsing with the OP web browser. In
origin to another. These vulnerabilities undermine the               IEEE Symposium on Security and Privacy, 2008.
same-origin policy and prevent Web sites from secur-
                                                                 [7] Jeremiah Grossman. Clickjacking: Web pages can
ing themselves against Web attackers. We present an
                                                                     see and hear you, October 2008.
algorithm for detecting cross-origin JavaScript capabil-
ity leaks by monitoring the “points-to” relation between         [8] Norm Hardy. The keykos architecture. Operating
JavaScript objects in the JavaScript heap. We imple-                 Systems Review, 1985.
ment our detection algorithm in WebKit and use it to             [9] Norm Hardy. The confused deputy: (or why capa-
find new cross-origin JavaScript capability leaks by run-            bilities might have been invented). SIGOPS Oper.
ning the WebKit regression test suite in our instrumented            Syst. Rev., 22(4):36–38, 1988.
browser. Having discovered these leaked pointers, we            [10] Ian Hickson et al. HTML 5 Working Draft.
turn our attention to exploiting these vulnerabilities. We
construct exploits to illustrate the vulnerabilities and find   [11] Collin Jackson and Helen J. Wang.           Sub-
that the root cause of the these vulnerabilities is the              space: Secure cross-domain communication for
mismatch in security models between the DOM, which                   web mashups. In Proceedings of the 16th Interna-
uses access control, and the JavaScript engine, which                tional World Wide Web Conference. (WWW), 2007.
uses object-capabilities. Instead of patching each leak,        [12] Peter-Paul Koch. Frame busting, 2004.
we recommend that browser vendors repair the under-                  http://www.quirksmode.org/js/
lying architectural issue by implementing access con-                framebust.html.
trol checks throughout the JavaScript engine. Although          [13] Butler Lampson. Protection and access control in
a straight-forward implementation that performed these               operating systems. Operating Systems: Infotech
checks for every access would have a prohibitive over-               State of the Art Report, 14:309–326, 1972.
head, we demonstrate that a JavaScript engine optimiza-         [14] Sergio Maffeis, John C. Mitchell, and Ankur Taly.
tion, the inline cache, reduces this overhead to 1–2%.               An operational semantics for JavaScript. In Pro-
Acknowledgements. We thank Chris Karloff, Oliver                     ceedings of the 6th Asian Programming Language
Hunt, Collin Jackson, John C. Mitchell, Rachel Parke-                Symposium (APLAS), December 2008.
Houben, and Sam Weinig for their helpful suggestions            [15] Mark Miller. A theory of taming.
and feedback. This material is based upon work par-
                                                                [16] Mark Miller. Caja, 2007.
tially supported by the National Science Foundation un-
der Grants No. 0311808, No. 0448452, No. 0627511,               [17] Mitre. CVE-2008-4058.
and CCF-0424422, and by the Air Force Office of Scien-          [18] Mitre. CVE-2008-4059.
tific Research under MURI Grant No. 22178970-4170.              [19] Mitre. CVE-2008-5512.
Any opinions, findings, and conclusions or recommen-
dations expressed in this material are those of the au-         [20] Mozilla. XPConnect wrappers.
thor(s) and do not necessarily reflect the views of the              http://developer.mozilla.org/en/
Air Force Office of Scientific Research, or the National             docs/XPConnect_wrappers.
Science Foundation.                                             [21] Sape J. Mullender, Guido van Rossum, Andrew
                                                                     Tannenbaum, Robbert van Renesse, and Hans van
References                                                           Staveren. Amoeba: A distributed operating system
 [1] Adam Barth, Collin Jackson, and John C. Mitchell.               for the 1990s. Computer, 23(5):44–53, 1990.
     Securing frame communication in browsers. In               [22] Prototype JavaScript framework.
     Proceedings of the 17th USENIX Security Sympo-                  http://www.prototypejs.org/.
     sium, 2008.                                                [23] Jonathan S. Shapiro, Jonathan M. Smith, and
 [2] Shuo Chen, David Ross, and Yi-Min Wang. An                      David J. Farber. Eros: a fast capability system. In
     analysis of browser domain-isolation bugs and a                 17th ACM Symposium on Operating System Prin-
     light-weight transparent defense mechanism. In                  ciples, New York, NY, USA, 1999. ACM.
     CCS ’07: Proceedings of the 14th ACM conference            [24] Maciej Stachowiak. Introducing SquirrelFish Ex-
     on Computer and communications security, pages                  treme, 2008.
     2–11, New York, NY, USA, 2007. ACM.
                                                                [25] Kris Zyp. CrossSafe.
 [3] Douglas Crockford. ADsafe.
You can also read