Information-Flow Security for a Core of JavaScript

Page created by Alvin Waters
 
CONTINUE READING
Information-Flow Security for a Core of JavaScript

                                             Daniel Hedin       Andrei Sabelfeld
                                    Chalmers University of Technology, Gothenburg, Sweden

   Abstract—Tracking information flow in dynamic languages             Securing mashups is subject to currently ongoing research
remains an important and intricate problem. This paper makes        efforts. A recent survey of the area [38] identifies a number
substantial headway toward understanding the main challenges        of approaches ranging from isolation of components to their
and resolving them. We identify language constructs that
constitute a core of JavaScript: objects, higher-order functions,   full integration. The focus of this paper is tight yet secure
exceptions, and dynamic code evaluation. The core is powerful       integration for scenarios when isolation is too restrictive and
enough to naturally encode native constructs as arrays, as well     full integration is insecure. In particular, we are interested
as functionalities of JavaScript’s API from the document object     in applications where access-control policies fall short and
model (DOM) related to document tree manipulation and event         where fine-grained information-flow control is desired.
processing. As the main contribution, we develop a dynamic
type system that guarantees information-flow security for this      Scenarios: To illustrate such applications, consider the
language.                                                           following scenarios. The scenarios are modeled on existing
                                                                    web pages, reflecting pervasive usage of advertising and
                                                                    statistics services on today’s web.
                      I. I NTRODUCTION
                                                                       Online advertisement: The first scenario is that of online
   Tracking information flow in dynamic languages remains           shopping. The online shopping code includes a third-party
an important and intricate problem. The goal of this paper          extension for dynamically generated ads. As items are put in
is understanding the fundamentals of challenges for tracking        the shopping cart, contextually dependent ads are displayed
information flow in dynamic languages and making substan-           to the user. The ads are tightly integrated in the shopping
tial headway to resolving them. We believe that with these          cart, mixing items with discount information, offers from
challenges addressed, our work opens up opportunities for           the merchant, and ads from cooperating third parties. This
practical security of dynamic applications that are hard to         is achieved by programmatic manipulation by JavaScript of
secure with existing approaches.                                    the nodes in the document object model (DOM) tree, a tree
Motivation: Modern web applications make increasingly               representation of the underlying document. This results in
intensive use of service composition. A particularly thriving       a highly dynamic information flow, where secret and public
service composition technique is client-side script inclusion.      information is mixed in the same linear structure.
It allows straightforward integration of services, often pro-          User tracking: The second scenario is that of a login to
vided by third parties, in so called web mashups. Popular           a bank. It illustrates event handling in terms of a keypad
examples of integrated services are Google Maps for vi-             for entering a shared secret. The keypad is part of an
sualizing data on interactive maps and Google Analytics             application that contains third-party code for creating click
for collecting statistics of web site usage. Extreme cases of       heat maps. Such third-party code is common on many web
third-party script inclusion can be found on sensitive web          sites. Consequently, the position of the clicks must be kept
sites like barclays.es, expedia.com, scrive.se, komplett.se,        secret from the heat map generator, since the positions of the
and webhallen.se, where the scripts are embedded at top             clicks encode information about what is entered via the key
level, often on the same page where the user enters lo-             pad. This implies that information flow through JavaScript
gin credentials. With user credentials at hand, integrated          event handlers must be secured.
client scripts have unrestricted power to engage in inter-             These scenarios motivate fine-grained security that is more
action with the hosting service. A directory for mashups at         permissive than full isolation (as provided by, e.g., iframes)
programmableweb.com contains more than 6000 registered              and at the same time more secure than full integration (as
mashups and more than 5000 registered content provider              provided by script inclusion with no additional measures).
API’s.                                                              Hence, our objective is to provide a solid foundation for
   The state of the art in web mashup security calls for            information-flow control to protect the user from malicious
improvement. The same-origin policy (SOP), enforced by              scripts run in a browser. To this end, the paper delivers the
most browsers today, is intended to restrict access between         following contributions.
scripts from different Internet domains. SOP offers an all-         Contributions: We identify a language that constitutes a core
or-nothing choice when including a script: either isolation,        of JavaScript and includes the following constructs: objects,
when the script is loaded in an iframe, or full integration,        higher-order functions, exceptions, and dynamic code eval-
when the script is included in the document via a script tag.       uation. We argue that the choice of the core captures the
essence of the language, and allows us to concentrate on        The challenge is identifying a subset of the standard that
the fundamental challenges for securing information flow        captures the core of JavaScript from an information-flow
in dynamic languages (Section II). While we address the         perspective, i.e., where the left-out features are either ex-
major challenge of handling dynamic language constructs,        pressible in the core, or where their inclusion does not reveal
we also resolve minor challenges associated with JavaScript.    new information-flow challenges. We identify the core of the
The semantics of the language closely follows the ECMA-         language to be: objects, higher-order functions, exceptions,
262 standard (v.5) [18] on the language constructs from the     and eval. In addition, we show that the well-known problems
core.                                                           associated with the JavaScript variable handling and the with
   We develop a dynamic type system for information-flow        construct can be handled via a faithful modeling in terms of
security for the core language (Section III) and establish      objects.
that the type system enforces a security policy of noninter-
ference [11], [22], that prohibits information leaks from the   B. Security challenges
program’s secret sources to the program’s public sinks (Sec-       Before presenting the security challenges, we briefly recap
tion IV). Corner cases of the soundness proof are formalized    standard information-flow terminology [15]. Traditionally,
in the proof assistant Coq [12]. We have implemented the        information flow analyses distinguish between explicit and
type system and performed a proof-of-concept indicative         implicit flows.
study of permissiveness using the scenarios above.                 Explicit flows amount to directly copying information,
   We show that the core is powerful enough to naturally        e.g., via an explicit assignment like l = h; , where the value of
encode native constructs as arrays, as well as functional-      a secret (or high) variable h is copied into a public (or low)
ities of JavaScript’s DOM API related to document tree          variable l. High and low represent security levels. We assume
manipulation and event processing (Section V). We develop       two levels without losing generality: our results apply to
these encodings as a part of our implementation for the two     arbitrary security lattices [14]. Security labels are used to
scenarios above.                                                store security levels for associated variables. In the following
   The first encoding implements parts of the core function-    let h and l represent high and low variables.
ality of the Document Object Model (DOM) [27] without              Implicit flows may arise when the control flow of the
imposing any constraints on the navigation. In particular,      program is dependent on secrets. Consider the program
direct indexing via the childNodes array, and node relocation   if (h) l = 1; else l = 0; . Depending on the secret stored in
when repeatedly adding the same node is fully supported.        variable h, variable l will be set to either 1 or 0, reflecting
The implementation only deals with the dynamic tree struc-      the value of h. Hence, there is an implicit flow from h into l.
ture of the DOM, in order to investigate the permissiveness     Frequently, this is tracked by associating a security label, the
of dynamic information flow. It does not obviate the need for   security context, with the control flow. Above, the body of
specific handling of the DOM in the form of, e.g., wrappers     the conditional is executed in a secret context. Equivalently,
implementing specific type rules, since the DOM is typically    the branches of the conditional are said to be under secret
not implemented in JavaScript.                                  control. The definition of public context and public control
   JavaScript does not include concurrency features. How-       are natural duals.
ever, the DOM API allows creating JavaScript handlers that
are triggered by external events and run without preemption.    Eval: The runtime possibility to parse and execute a string
The second encoding implements a simplified version of          in a JavaScript program, provided by the eval instruction,
the events of JavaScript, and shows how the propagation         poses a critical challenge for static program analyses, since
of events can be controlled, including how events can be        the string may not be available to a static analysis.
stopped, the presence of certain events can be made secret,        Our approach: Dynamic analyses do not share this limita-
or how the presence of events can be public, while the data     tion, by virtue of the fact that dynamic analyses are executed
of the event remains secret.                                    at runtime. This is one of the two main reasons for the use
                                                                of a dynamic type system in this paper.
         II. C HALLENGES AND OUR APPROACH
   The ultimate goal of this work is to enforce information-    Aliasing and flow sensitivity: The type system of JavaScript
flow security in JavaScript. This section outlines the main     is flow sensitive; the types of, e.g., variables and fields
challenges and illustrates our approach to resolving them.      are allowed to vary during the execution. In addition, ob-
                                                                jects in JavaScript are heap allocated and represented by
A. Language challenges                                          primitive references — their heap location. Hence, objects
   JavaScript is a dynamically typed, object-based language     in JavaScript may be aliased. An alias occurs when two
with higher-order functions, and dynamic code evaluation        syntactically different program locations (e.g., two variables
via, e.g., the eval construction. The voluminous ECMA-262       x and y) refer to the same object (contain the same primitive
standard describes the syntax and semantics of JavaScript.      reference).
Flow sensitivity in the presence of aliases poses a signifi-    Permissiveness: As is, no sensitive upgrade prevents af-
cant challenge for static analyses, since changing the labels      fecting public locations under secret control. This poses a
of one of the locations requires that the security labels of       permissiveness challenge: how to secure programs where
all aliased locations are changed as well, which requires the      public locations must be assigned under secret control.
static analysis to keep track of the aliasing.                        Our approach: We address the challenge by facilitating
   Our approach: Dynamic approaches do not share this              upgrade of the security label before entering the secret
limitation, since they are able to store the security label in     control via the addition of a number of upgrade instructions
the referred object instead of associating it with the syntactic   to the language. All but one of the upgrade instructions is
program location. Consider the following program:                  expressible in the language. Thus, the addition is merely one
x = new O b j e c t ( ) ; x . f = 0 ; y = x ; y . f = h ;          of convenience and does not extend the language.
                                                                      Also note that the upgrade instructions are not necessary
First, a new object is allocated and the primitive reference       for the soundness of the system. They may be used to
to the object is stored into x. Thereafter, the field f of the     increase the permissiveness of the type system by com-
newly allocated object is set to 0, and y is made an alias of      municating security policies to the runtime type checker.
x, and the field f is overwritten by a secret via y. This kind     Although they can be used as part of the programming
of programs are rejected by static analysis like Jif [32]. In      language, in order to support legacy code it is more fruitful
the dynamic setting, we simply update the security label of        to view it as a way to incorporate the results of an au-
the value of the field f of the allocated object. This is the      tomatic analysis. We have successfully experimented with
second main reason for the use of a dynamic type system            the use of automatic black-box testing to inject the upgrade
in this paper.                                                     instructions [7]. The idea is to run a modified version
Dynamic flow sensitivity: There is a known limitation [21],        of the type system on automatically generated test cases,
[36] of the flow sensitivity of dynamic analyses. Consider the     and, whenever the type system stops the execution, the
following example, where we assume h is 1 or 0 originally:         trace of the execution is inspected to find the place in the
l = 1 ; t = 0 ; i f ( h == 1 ) t = 1 ; i f ( t ! = 1 ) l = 0 ;
                                                                   program where an upgrade instruction must be inserted.
                                                                   The inserted upgrade instructions prevent the monitor from
If security labels are allowed to change freely under secret       blocking the program and thus help avoiding false positives.
control, the above program results in the value of h being         Our experiments for a language with records and exceptions
copied into l without changing the security label of l.            indicate that random testing accurately discovers annotations
   Our approach: In order to prevent such leaks it suffices        for a collection of scenarios with rich information flows.
to disallow security label upgrades under secret control.          Upgrade of the values of variables and fields: In order to
This corresponds to Austin and Flanagan’s no sensitive             write to variables or fields under secret control, the language
upgrade [2] discipline. Hence, the execution of the above          provides instructions that upgrade the security label of the
program is stopped with a security error.                          value of the variable or field. For instance, the example from
Structure and existence: Not only the values of fields can         the discussion on dynamic flow sensitivity above can be
be used to encode information, but also their presence or          secured by adding appropriate upgrades:
absence. Consider the following example:                           l = 1 ; t = 0 ; upg t ; i f ( h == 1 ) t = 1 ;
                                                                                   upg l ; i f ( t ! = 1 ) l = 0 ;
i f ( h) o . q = 0;
                                                                   By upgrading the security label of the value of t before
After execution of the conditional the answer to the question      the conditional in which t is assigned we guarantee that the
whether q is in the domain of o gives away the value of h.         security label of the value of t is independent of secrets and
It is important to note that not only the presence, but also       compatible with the assignment (analogously for l). This
the absence, of q gives away information — copying the             renders a program that runs for all values of h, and where
value of h into l via the presence/absence of q can easily         the results stored in variables t and l are always secret.
be done by executing l = (o.q == undefined ); , since projecting   Upgrade of object structure and field existence: Addition
non-existing fields returns undefined.                             and deletion of fields under secret control is only allowed
   Our approach: We solve this by associating an existence         on structurally secret records: the existence of the added field
security label with every field, and a structure security label    becomes secret, and only fields with a secret existence label
with every object, demanding that addition of new fields           are allowed to be removed. To enable fields to be added
under secret control is possible only if the structure of the      or deleted under secret control the structure security label
object is secret. Once the structure of an object is secret,       of the record must be raised, as illustrated in the example
knowing the absence of fields in the object is also secret. In     below:
the example above o.q would have secret existence security
                                                                   upg s t r u c t o ; i f ( h ) o . g = 1 ;
labels, and the structure of o would have to be secret for the     upg e x i s t e n c e o . x ; upg e x i s t e n c e o . y ;
body of the conditional to be allowed to be executed.              if (h) delete o . x ; else delete o . y ;
Finally, it is not possible to express the upgrade of the       assignment to l2 will be run. Thus, the update of l2 is
existence security label of variables or of the structure          public, whereas the update of l1 remains secret. The ex-
security label of environment records (see Section III-B).         ception handler is run under secret control given that the
Under some circumstances this hinders addition and deletion        exception label is secret. The exception security label of
of variables under secret control. However, this restriction is    the handler, however, is the initial exception security label,
in line with the design of JavaScript, where variable hoisting     which means that exceptions are not allowed in the handler,
serves the purpose to make variable declarations independent       unless exceptions under secret control are allowed by the
of the control structure.                                          outer exception security label.
                                                                      Although the language must be extended with non-
Exceptions: Exceptions offer further intricacies, since they
                                                                   standard constructs to handle upgrading of the exception
allow for non-local control transfer. Any instructions fol-
                                                                   security label this is not a fundamental limitation. Under
lowing an instruction that may throw an exception based on
                                                                   the assumption that normal execution is prevalent, i.e., that
a secret must be seen as being under secret control, since,
                                                                   the exceptions are used only in cases where there is a failure.
similar to the conditional, the instruction may or may not
                                                                   For such cases, the exception security label instruction can
be run based on whether the exception is thrown or not.
                                                                   be provided in order to increase the permissiveness of the
Consider the following example:
                                                                   system. In the case the instruction is not made available only
l = t r u e ; i f ( h ) { throw 0 } ; l = f a l s e ;              programs that must be able to recover secret exceptions are
Whether h is 0 or not controls whether the update is run or        affected.
not and hence l encodes information about h.                       Higher-order functions: Being first class values, functions
   Our approach: The default-allow policy for exceptions           carry a security type that must be taken into consideration
is clearly too restrictive — it would force us to treat all        when calling the function. Consider the following example,
side effects after the first possible exception under secret       where a secret function f is created by choosing between
control as secret. Instead, we introduce a dynamic security        two functions under secret control.
label for exceptions. If the exception security label is public,   f = i f ( h ) { f u n c t i o n g ( x ) { l = 1 ; }}
exceptions under secret control are prohibited. If, on the             else      { f u n c t i o n g ( x ) { l = 0 ; }}
other hand, the security label is secret, any side effects are
treated as if they were under secret control.                      Depending on the secret h, a function that writes 1, or a
   Let us return to the example above. Since the exception         functions that write 0 to l is chosen, and applying the result
security label in the example is public, the conditional is        copies the value of h into l.
prevented from throwing exceptions and the update of l                Our approach: The body of the function must be run in a
can proceed without restrictions. If we want to allow the          security context that is at least as secret as the security label
exception to be thrown, however, we upgrade the exception          of the function. This discipline is inspired by static handling
security label, in which case the update of l will be treated      of higher-order functions [33].
as being under secret control. On that account, the language       Variables and scoping: JavaScript is known for its non-
provides an upgrade instruction upg exc that upgrades the          standard scoping rules. Variable hoisting in combination
exception security label. Note that this instruction is not        with non-syntactic scoping, the with and eval constructions,
expressible in the language.                                       and the fact that updating non-existing variables will define
   To make the example above run properly we must upgrade          the variable in the global variable environment, cause com-
both the exception security label and the security label of        plex and sometimes unexpected behavior. To appreciate this
the variable l.                                                    consider, for instance, conditional shadowing using eval.
l = t r u e ; upg l ; upg e x c ;                                  f = f u n c t i o n f ( x ) { i f ( h ) { e v a l ( ” var l ” ) } ; l = 0}
i f ( h ) { throw 0 } ; l = f a l s e ;
                                                                   In order to understand this example we must know more
   Clearly, secret exceptions would be rather prohibitive if       about functions and scoping in JavaScript. First, the variable
there was no way of lowering the exception security label. To      environments form a chain. Variable lookup starts in the
this extent, the body of the try-catch statement can be used       topmost environment and continues down the chain until
to encapsulate exception security label upgrades. Consider         the variable has been found or the end of the chain — the
the following example:                                             global variable environment — has been reached.
l1 = t r u e ; upg l1 ;                                               Second, both if and eval are unscoped, i.e., the variable
t r y { upg e x c ; i f ( h ) { throw 0 } ; l1 = f a l s e ; }     declared by the eval is declared in the topmost variable
c a t c h ( x ) { s k i p } ; l2 = 1 6 ;
                                                                   environment of the function call. The use of eval is to pre-
In this example, since the upgrade of the exception security       vent variable hoisting until the execution of the conditional
label occurs inside a try-catch statement , we know that           branch. Otherwise, l would be hoisted out of the if and
regardless of whether an exception is thrown or not the            always be declared regardless of the value of h.
Execution of f is split into two cases. If h is true, the
variable is defined locally in the function, and the update of      e   ::=    s | n | b | undefined | null | this | x | e1 [e2 ] | e1 = e2
l is captured by the local l. If h is false, l is created in the           |   delete e | typeof (e) | e1 ? e2 | e(e) | new e(e)
                                                                           |   function x(x) c
global variable environment (unless it already exists). Hence,      c   ::=    var x | c1 ; c2 | if (e) c1 else c2 | while (e) c
both the value of l in the global variable environment and                 |   for (x in e) c | throw e | try c1 catch(x) c2 | return e
potentially its existence encodes information about h. The                 |   eval e | with e c | skip | upg l | e
                                                                    l   ::=    e | existence e | struct e | exc
latter implies that we must track the structure of variable
environments, similar to objects above. In addition, the
presence or absence of the l in the local variable environment     A. Syntax
(or somewhere else in the chain in general) effects where the         Let X range over lists of X, where · denotes the cons
update takes place. This means that, when reading or writing       operator and [ ] denotes the empty list, e.g., x denotes lists
to variables, the structure security labels encountered during     of variable names, and e denotes lists of expressions.
the traversal of the variable chain must be taken into account.       The syntax of the language consists of two basic syntactic
   Our approach: We show that the intricate variable behav-        categories: expressions, ranged over by e, and statements,
ior of JavaScript can be handled by a faithful modeling of         ranged over by c.
the execution context in terms of objects.                            Unary operators are represented by delete, and typeof,
                                                                   and, without loss of generality, the binary operators are
C. From the core to full JavaScript                                opaquely represented by ?. In addition, the empty statement
                                                                   is represented by a distinguished skip statement and the
   The core has been selected to be representative of the
                                                                   language is extended with nonstandard constructions for
information flow challenges of JavaScript. The simplifica-
                                                                   security label upgrade of variables and fields, existence
tions and omissions have been chosen to not exclude any
                                                                   security labels of fields, structure security labels of objects
information flow challenges. Hence, our approach is not a
                                                                   and the exception security label, explained in Section II-B.
sub-language approach. Rather we envision that extension
                                                                   For simplicity we assume that each function contains exactly
to the full language is possible without further technical
                                                                   one return statement, and that it occurs as the last statement
development.
                                                                   in the body of the function. Also, in the following, we
   In addition, even though property attributes and other
                                                                   identify string literals and variable names, writing s instead
ECMA-262 (v.5) features like the ability to freeze objects
                                                                   of ”s”.
and strict mode are important from a security perspective and
might simplify enforcement of secure information flow we           B. Semantics
cannot assume that code is strict mode without sacrificing            The semantics of the language is given in big-step oper-
the possibility of handling legacy code. For this reason, we       ational form and provides dynamic security type checking.
target the non-strict semantics of ECMA-262 (v.5).                    This section consists of two parts. First, we introduce
   With the intuition on the challenges and their resolution       the values including a primitive notion of objects, the basis
at hand, we are now ready to proceed to the formal devel-          for the formulation of ECMA objects. This provides func-
opment: the presentation of the dynamic type system and its        tionality for basic object interaction, extended to function
soundness.                                                         objects, providing function call, and object construction via
                                                                   constructor functions, and environment records, providing
                       III. L ANGUAGE                              the foundation for the lexical and variable environments.
                                                                   Second, we introduce the semantics of expressions and
   The semantics is a subset of the non-strict semantics of        statements in terms of the development of the first part.
ECMA-262 (v.5) standard. In order to aid the verification of          This stepwise construction allows for most of the
the semantics and increase confidence in our modeling we           information-flow control to be pushed into the basic prim-
have chosen to follow the standard closely.                        itives, simplifying the formulation of more complex func-
   The semantics is instrumented to track information flow         tionality and their explanation.
with respect to a two-level security lattice, classifying in-
formation as either public or secret, preventing secret infor-          v   ::=   r | s | n | b | undefined          p ::= v̇ | F | c | x
                                                                                       σ1                 σn
mation from affecting public information. This is achieved              o   ::=   {s1 7→  p1 , . . . , sn 7→ pn , σ}
by stopping the execution when potential leaks are detected,
which is expressed in the semantics by not providing reduc-        Values: Let H (secret) and L (public) be security labels,
tion rules for the cases that may cause insecure information       ranged over by σ, used to label the other values with security
flow. Stopping the execution when security violations are          information. For clarity in the semantic rules, let pc and 
detected may introduce a one-bit information leak, which is        range over security labels in the function of security context
reflected in our baseline security condition in Section IV.        and the exception security label, see Section II-B.
The primitive values, ranged over by v, are primitive           containing the field together with field name. When reading,
references (i.e., opaque pointers), strings, numbers, booleans,    the result is raised to security label of the read context.
and the undefined value. Similarly to security labels above,          The write context of an entity is the read context together
r ranges over primitive references in general, while le, ve,       with the security context and the exception security label.
and τ range over primitive references when denoting lexical        When writing to an entity the demand is that the security
environments, variable environments, and the this binding,         label of the entity is at least as secret as the write context
defined below.                                                     of the entity. This ensures that the security labels are
   In the instrumented semantics all primitive values occur        independent of secrets.
together with a security label representing the security clas-
sification of the value. Let v σ be security labeled primitive        We define ECMA Objects to be primitive objects extended
values, written v̇ when
                     σ2
                           the actual security label is unimpor-   with a relevant selection of the core functionality. In partic-
tant. Let v̇ σ2 = v σ1 = v σ1 tσ2 .                                ular, an ECMA Object O is defined by
   The references, (ṙ, ṡ), are pairs of security labeled prim-
itive references and strings, denoting a field in an object.            O={    GetOwnProperty 7→ GetOwnProperty,
In the following we let v̇ range over both security labeled                    GetProperty 7→ GetProperty,
value and references, (ṙ, ṡ).                                                HasProperty 7→ HasProperty,
                                                                               Delete 7→ Delete, Get 7→ Get, Put 7→ Put }
   In addition to the primitive values, the notion of primitive
object, ranged over by o, forms the foundation of the
                                                                   The rules for ECMA Objects are found in Table I.
semantics of JavaScript. A primitive object is a map from
strings to properties, decorated with existence and structure
security labels, see Section II-B. The fields are either in-       GetOwnProperty: Given a primitive reference and field
ternal or external indicated by the IsExternal predicate on        name GetOwnProperty returns a property descriptor,
strings, which is false for strings of the form s and true         {value 7→ v̇} containing the value of the field or undefined
otherwise. Internal fields are used in the implementation of       in the case the field does not exists. In both cases the
the semantics but are not exposed to the programmer —              security label of the result is raised to the read context
see the semantics of for-in below. The properties of external      (i.e. the primitive reference and field name). As discussed in
fields are security labeled primitive values, while internal       Section II-B the structure security label is taken into account
fields may hold algorithms represented by general functions,       for non-existing fields.
F, statements, c, and lists of formal parameters, x.               GetProperty: Let d range over property descriptors or
   The heap, ranged over by φ, is a mapping from primitive         undefined, d ::= {value 7→ v̇}|undefined σ , and let dσ be
references to primitive objects. The execution environment         defined structurally in the immediate way. GetProperty is
E ::= (φ, ) is a pair of a heap, φ, and an exception security     formulated in terms of GetOwnProperty and follows the
label, . Let E[r] = φ[r] for E = (φ, ). In addition,             prototype chain [18] while searching for the field. During
execution takes place with respect to an execution context         the search the security labels of the primitive references and
             ˙ ve),
C ::= (τ̇ , le, ˙ built up by the this binding, τ , a primitive    of the GetOwnProperty results are accumulated and used to
reference, le, to the topmost lexical environment, and a           raise the final result, cf. the notion of read context and access
primitive reference, ve, to the topmost variable environment.      path.
Let u̇ denote exception lifted values, i.e., u̇ ::= v̇ | exc v̇.   HasProperty: HasProperty is a boolean valued wrapper
                                                                   around GetProperty, i.e., it returns true if the field exists
ECMA Objects: All objects of JavaScript define a number            and false otherwise.
of internal algorithm fields that provide a common interface       Delete: Delete deletes fields of objects. Given a primitive
for interacting with the object. Most of the standard is           reference to a primitive object and a field name the field
described in terms of this interface; only few algorithms          is removed from the object. Deleting an existing field from
manipulate the primitive objects directly. This common core        an object, changes the structure of the object, which causes
provides an ideal location for handling information flow           the demand that the write context of the object is below
security. By showing that the core is secure we can easily         the structure label, and similarly for the existence, see
establish (by using compositionality of our security notion)       Section II-B. Similar to the update below, the structure
that more complex functionality formulated in terms of the         security label is raised to the security label of the field name.
core is secure as well.                                            Get: Given a primitive reference and a field name Get uses
   The explanation of information flow in an object oriented       GetOwnProperty to obtain a property descriptor and returns
language is facilitated by the notions of read context, and        the value of the field or undefined if the field does not exist.
write context. The read context for an entity is the accumu-       Put: Of the ECMA object algorithms Put is the most com-
lated security label of the access path of the entity. For a       plicated from an information-flow perspective. It provides
field, the access path is the primitive reference to the object    addition and update of the fields of objects, with different
3 σ
                              o = E[r]      o = {s 7→  v̇, . . . }                                   o = E[r]        s 6∈ dom(o)        o = {. . . , σ3 }
            GetOwnProperty(rσ1 , sσ2 ) E = {value 7→ v̇ σ1 tσ2 tσ3 }                          GetOwnProperty(rσ1 , sσ2 ) E = undefined σ1 tσ2 tσ3
                                                                                             GetOwnProperty(ṙ, ṡ) E = undefined σ1
                              GetOwnProperty(ṙ, ṡ) E = {value 7→ v̇}                        o = E[r]   o[ Prototype ] = null σ2
                               GetProperty(ṙ, ṡ) E = {value 7→ v̇}                         GetProperty(ṙ, ṡ) E = undefined σ1 tσ2
                                GetOwnProperty(ṙ1 , ṡ) E = undefined σ1
                   o = E[r1 ]     o[ Prototype ] = ṙ2      GetProperty(ṙ2 , ṡ) E = d                       GetProperty(ṙ, ṡ) E = {value 7→ pσ }
                                      GetProperty(ṙ1 , ṡ) E = dσ1                                              HasProperty(ṙ, ṡ) E = true σ
                                                                                         σ
                                                                                         3
         GetProperty(ṙ, ṡ) E = undefined σ                      o = φ[r]      o = {s 7→  v̇, . . . , σ4 }      σ = pc t  t σ1       σ
records, chained together by chaining objects, C(r1 , ṙ2 ) =            Call , and Construct . Let F denote the family of
{ EnvironmentRecord     7→ r1 , OuterEnvironment     7→ ṙ2 },          function objects
where EnvironmentRecord points to the environment
record, and OuterEnvironment points to the next chaining                     F(x, c, ṙ) = O[   Scope 7→ ṙ, FormalParameters 7→ x,
                                                                                                Code 7→ c, Call 7→ FunctionCall,
object in the chain. The environment records store                                              Construct 7→ FunctionConstruct ]
the variable bindings and come in two forms: object
environment records and declarative environment records                 Call: Calling a user defined function first allocates a new
differing in whether a separate object, the binding object,             declarative environment in which the arguments are bound
is used to store the variable bindings or if the bindings are           by a process called declaration binding. Thereafter the body
stored in the environment record itself. Another difference             of the function is executed in the updated context. Note that
is in the implementation of the ImplicitThisValue, for which            the creation of the declarative environment, the declaration
the object environment record returns the binding object                binding, and the body are run in a security context raised
and the declarative environment record returns null.                    to the security label of the primitive reference, rF , of the
   We simplify object environment records and declarative               function, as is the returned value, see Section II-B.
environment records to support the same subset of oper-
ations: HasBinding, GetBindingValue, SetMutableBinding,                             F = E1 [rF ]                            pc 2 = pc 1 t σ
DeleteBinding, and ImplicitThisValue.                                    (ṙ, E2 ) = pc 2 ` NewDeclarativeEnvironment(F[ Scope ]σ ) E1
                                                                                     E3 = pc 2 , ṙ ` DeclarationBinding(F, a) E2
   The NewDeclarativeEnvironment algorithm allocates                               pc 2 , (this(ṙt ), ṙ, ṙ) ` hF[ Code ], E3 i → hu̇, E4 i
a new declarative environment and links it onto the                                                           σ , a) E = (u̇σ , E )
                                                                                   pc 1 ` FunctionCall(ṙt , rF       1          4
given environment record chain, and similarly for the
NewObjectEnvironment algorithm for object environ-                         where this(undefined σ ) = rGσ
                                                                                                          , and this(ṙ) = ṙ, oth-
ments.                                                                  erwise. (Recall that rG is the primitive reference to the
                                                                        global object defined above.) See below for the definition
         r1 , r2 fresh     E2 = E1 [r1 7→ DE, r2 7→ C(r1 , ṙ)]
                                                                        the semantics of statements used to evaluate the body,
      pc ` NewDeclarativeEnvironment(ṙ) E1 = (r2L , E2 )
                                                                        F[ Code ].
      r3 , r4 fresh      E2 = E1 [r3 7→ OE(ṙ2 ), r4 7→ C(r3 , ṙ1 )]
                                                                        Declaration binding: Declaration binding first binds the
       pc ` NewObjectEnvironment(ṙ1 , ṙ2 ) E1 = (r4L , E2 )           arguments of the function call and then performs variable
                                                                        hoisting.
Get identifier reference: GetIdentifierReference takes a
primitive reference to the topmost variable environment and               E2 = pc, ṙ ` BindParameters(F[ FormalParameters ], a) E1
a variable name and traverses the chain of environment                            E3 = pc, ṙ ` HoistVariables(F[ Code ]) E2
records until the variable is found or the chain ends. The                          pc, ṙ ` DeclarationBinding(F, a) E1 = E3
returned result is a reference (ṙ, xL ) where x is the name of
the variable and r is a primitive reference to the environment             The parameters are bound by ignoring any surplus param-
record containing the variable, or undefined if the variable            eters, and setting missing parameters to undefined .
was not found.
                                                                                       pc, ṙ ` BindParameters([ ], ) E = E

     GetIdentifierReference(null σ , x) E = (undefined σ , xL )                    E2 = pc ` ṙ. SetMutableBinding (xL , v̇) E1
         r1 6= null    r2 = E[r1 ][ EnvironmentRecord ]                               E3 = pc, ṙ ` BindParameters(x, v) E2
               true σ2 = r2σ1 . HasBinding (xL ) E                                 pc, ṙ ` BindParameters(x · x, v̇ · v) E1 = E3
          GetIdentifierReference(r1σ1 , x) E = (r2σ2 , xL )
                                                                             E2 = pc ` ṙ. SetMutableBinding (xL , undefined L ) E1
         r1 6= null      r2 = E[r1 ][ EnvironmentRecord ]                           E3 = pc, ṙ ` BindParameters(x, [ ]) E2
                false σ2 = r2σ1 . HasBinding (xL ) E                              pc, ṙ ` BindParameters(x · x, [ ]) E1 = E3
                   ṙ3 = E[r1 ][ OuterEnvironment ]
           (ṙ4 , ẋ) = GetIdentifierReference(ṙ3σ2 , x) E                Variable hoisting traverses the body of the function and
            GetIdentifierReference(r1σ1 , x) E = (ṙ4 , ẋ)             defines all variables, initializing them to undefined . The
                                                                        hoisting algorithm HoistVariables is easily formulated and
Function objects: Function objects are objects containing               can be found in the full version of the paper [26].
two internal properties, Call , used by function application            Construct: Object construction via user defined functions
and Construct , used in object construction.                            uses the function as an initializer on a newly allocated
User defined function objects: The function objects created             ECMA object. Before passing the object, the Prototype
when evaluating function expressions are closures storing the           field is set to the value of the prototype field of the
context the function was created in, the formal parameters of           constructor function, after which the object is initialized by
the function and the code of the function, used by associated           calling the constructor function using the primitive reference
to the object as the this argument. Without loss of generality,         All rules that contain evaluation of subexpressions use
we assume that all constructor functions return a primitive             GetValue to convert the results to values, assignment uses
reference to the new object.                                            PutValue to update the location denoted by the refer-
                                                                        ence. delete uses Delete or DeleteBinding depending on
            (ṙ1 , E2 ) = NewEcma E1         pc 2 = pc 1 t σ            if the target is an object or an environment record (in-
                            σ . Get (prototype) E
                     ṙ2 = rF                         2
                                                                        dicated by IsPropertyReference). Function creation uses
            E3 = pc 2 ` ṙ1 . Put ( Prototype L , ṙ2 ) E2
                                                      σ , a) E
           (u̇, E4 ) = pc 2 ` E3 [rF ][ Call ](ṙ1 , rF       3
                                                                        NewDeclarativeEnvironment to allocate the local variable
                                   σ , a) E = (u̇σ , E )
         pc 1 ` FunctionConstruct(rF
                                                                        environment, NewFun to create the new function object and
                                           1          4
                                                                        SetMutableBinding to initialize the new environment by
  In the following let NewFun allocate and set up a new                 binding the function name to the newly created function ob-
function object from the given list of formal parameters,               ject in order to allow for recursive calls. Function application
function body and scope.                                                uses Call , and object creation uses Construct.
                                                                            The field projection, assignment, object construction, and
   r1 fresh     E2 = E1 [r1 7→ F(x, c, ṙ)] (ṙ2 , E3 ) = NewEcma E2    binary operators all use the evaluation of a list of expressions
                E4 = pc ` ṙ2 . Put (constructor L , r1L ) E3           pc, C ` he, E1 i → hv, E2 i, which returns a list of security
                 E5 = pc ` r1L . Put (prototype L , ṙ2 ) E4            labeled values.
                   pc ` NewFun(x, c, ṙ) E1 = (r1L , E5 )                   Note the this(v̇) E3 of the function call, which computes
                                                                        the this binding of the invocation, from the reference v̇ =
Auxiliary reference functions: GetValue fetches the value               (r, s)σ : 1) if the base of the reference, r, is undefined, or
associated with a reference; non-reference values are re-               if it is a property reference then the base of the reference
turned untouched. Subject to the limitations of Section II-B            is returned, otherwise, 2) the base is an environment record
an exception is raised if the reference is undefined.                   and the result of calling ImplicitThisValue is returned.
                                                                            Finally, note how typeof returns undefined for undefined
                                                                        variables, whereas using an undefined variable in, e.g., a
                      pc ` GetValue(v σ ) E = v σ
                                                                        binary operator would cause an exception when trying to
                  v̇ = ṙ. Get (ṡ) E  r 6= undefined                   apply GetValue on the reference. This is the reason typeof
                      pc ` GetValue((ṙ, ṡ)) E = v̇                    can be used to detect whether variables are defined or not.
                 σ t pc
pc, C ` he, E1 i → hv̇1 , E2 i
                                                                                                                          v̇2 = pc ` GetValue(v̇1 ) E2
   pc, C ` hs|n|b|undefined, Ei →          hs L |n L |b L |undefined L , Ei                                                 pc, C ` he, E2 i → ha, E3 i
                                                                                   pc, C ` h[ ], Ei → h[ ], Ei
                                        ˙ ve)
pc, C ` hnull, Ei → h0L , Ei pc, (τ̇ , le, ˙ ` hthis, Ei → hτ̇ , Ei                                                     pc, C ` he · e, E1 i → hv̇2 · a, E3 i
                                                          pc, C ` h[e1 , e2 ], E1 i → h[v̇1 , v̇2 ], E2 i        pc, C ` h[e1 , e2 ], E1 i → h[v̇1 , v̇2 ], E2 i
                                                               ṙ = pc ` GetValue(v̇1 ) E2                            v̇3 = pc ` GetValue(v̇2 ) E2
     v̇ = GetIdentifierReferece(le,  ˙ x) E                    ṡ = pc ` GetValue(v̇2 ) E2                         E3 = pc ` PutValue(v̇1 , v̇3 ) E2
                   ˙   ˙ ` hx, Ei → hv̇, Ei
        pc, (τ̇ , le, ve)                                  pc, C ` he1 [e2 ], E1 i → h(ṙ, ṡ), E2 i               pc, C ` he1 = e2 , E1 i → hv̇3 , E3 i
    pc, C ` he, E1 i → h(ṙ, ṡ), E2 i                                                                                pc, C ` he, E1 i → h(ṙ, ṡ), E2 i
   IsPropertyReference((r, s)) E2                                                                                   ¬IsPropertyReference((r, s)) E2
  (v̇, E3 ) = pc ` ṙ. Delete (ṡ) E2               pc, C ` he, E1 i → h(undefined σ , ṡ), E2 i               (v̇, E3 ) = pc ` ṙ. DeleteBinding (ṡ) E2
  pc, C ` hdelete e, E1 i → hv̇, E3 i                 pc, C ` hdelete e, E1 i → htrue L , E2 i                       pc, C ` hdelete e, E1 i → hv̇, E3 i
        pc, C ` he, E1 i → hv̇, E2 i ṙ = pc ` GetValue(v̇) E2                        pc, C ` he, E1 i → hv̇, E2 i ṙ = pc ` GetValue(v̇) E2
                        pc, C ` he, E2 i → ha, E3 i                                                    pc, C ` he, E2 i → ha, E3 i
          (u̇, E4 ) = pc ` E3 [r][ Call ](this(v̇) E3 , ṙ, a) E3                           (u̇, E4 ) = pc ` E3 [r][ Construct ](ṙ, a) E3
                      pc, C ` he(e), E1 i → hu̇, E4 i                                             pc, C ` hnew e(e), E1 i → hu̇, E4 i
              (leσ                                                    ˙
                 2 , E2 ) = pc ` NewDeclarativeEnvironment(le1 ) E1                                             pc, C ` h[e1 , e2 ], E1 i → h[v̇1 , v̇2 ], E2 i
 (ṙf , E3 ) = pc ` NewFun(x, c, leσ     2 ) E2   ṙ = E3 [le2 ][ EnvironmentRecord ]                               v3σ1 = pc ` GetValue(v̇1 ) E2
                      E4 = ṙσ . SetMutableBinding (xL , ṙf ) E3                                                   v4σ2 = pc ` GetValue(v̇2 ) E2
                            ˙ 1 , ve)
                 pc, (τ̇ , le      ˙ ` hfunction x(x) c, E1 i → hṙf , E4 i                                 pc, C ` he1 ? e2 , E1 i → h(v3 ? v4 )σ1 tσ2 , E2 i
                                                                                             pc, C ` he, E1 i → h(ṙ, ṡ), E2 i
                              pc, C ` he, E1 i → hv σ , E2 i                          r 6= undefined    v σ = GetValue((ṙ, ṡ)) E2
                     pc, C ` htypeof (e), E1 i → htypeof (v)σ , E2 i                  pc, C ` htypeof (e), E1 i → htypeof (v)σ , E2 i
                                                         pc, C ` he, E1 i → h(undefined σ , ṡ), E2 i
                                                       pc, C ` htypeof (e), E1 i → hundefined σ , E2 i

                                                                          Table II
                                                                 S EMANTICS OF EXPRESSIONS

            pc, C ` hc1 , E1 i → E2                     pc, C ` he, E1 i → htrue σ , E2 i                      pc, C ` he, E1 i → hfalse σ , E2 i
            pc, C ` hc2 , E2 i → E3                       pc t σ, C ` hc1 , E2 i → E3                             pc t σ, C ` hc2 , E2 i → E3
           pc, C ` hc1 ; c2 , E1 i → E3             pc, C ` hif (e) c1 else c2 , E1 i → E3                  pc, C ` hif (e) c1 else c2 , E1 i → E3
                                                                pc, C ` he, E1 i → htrue σ , E2 i
pc, C ` he, E1 i → hfalse σ , E2 i            pc t σ, C ` hc, E2 i → E3      pc t σ, C ` hwhile (e) c, E3 i → E4
                                                                                                                                    pc, C ` h([ ], v̇, c), Ei → hEi
pc, C ` hwhile (e) c, E1 i → E2                                pc, C ` hwhile (e) c, E1 i → E4
IsExternal(s) E2 = pc ` PutValue(v̇, sσ ) E1
                                                                                                                                     pc
The throw demands that the security context pc is below         noninterference is a natural fit for the monitor because it
the exception security label , as does the exception security     justifies the blocking upon detecting a security violation.
label upgrade statement.
   The execution of try-catch is divided into normal and           A. Low-equivalence
exceptional execution of the body. In the first case, the result      Noninterference is formulated in terms of a family of low-
of the execution is returned in the outer exception context,       equivalence relations · ∼· · for values, objects, heaps, and
i.e., the exception security label of the try-catch. This allows   environments. The family of relations is defined structurally,
for containing exception security label upgrades to the try-       demanding that equivalent values carry equal security labels,
catch. In the second case, if an exception is thrown in the        and in the case the label is public that values are equal. The
body of the try-catch, control is passed to the exception          definition of the low-equivalence relation can be found in
handler. The body of the handler is run in a new lexical           the full version of the paper [26].
environment, in which the formal parameter of the handler
is bound to the exception value. This means that variables         B. Noninterference
declared in the body of the handler are not contained to the          Two statements c1 and c2 are noninterfering, ni(c1 , c2 ),
body of the handler, similar to eval and with above. With          if any pair of terminating runs, starting from low-equivalent
respect to information flow, the body of the handler is run        execution environments, results in low-equivalent execution
in a security context which is the least upper bound of the        environments:
initial security context and the exception security label at
the program point where the exception was thrown. This               ni(c1 , c2 ) = E1 ∼β1 ,1 E2 ∧ C1 ∼β1 C2 ∧
guarantees that the body of the handler is unable to leak             L, C1 ` hc1 , E1 i → hu̇1 , E10 i ∧ L, C2 ` hc2 , E2 i → hu̇2 , E20 i ⇒
information about the existence of secret exceptions. Further,                           ∃β2 , 2 . β1 ⊆ β1 ∧ hu̇1 , E10 i ∼β2 ,2 hu̇2 , E20 i
the body of the handler is run in the outer exception security
level, since any (uncaught) exceptions in the handler escape          We prove the security of the dynamic type system by
the try-catch.                                                     establishing that all terminating runs of all programs are
   The eval statement evaluates its argument, parses the           noninterfering:
result to a program, which is run after hoisting the variables     Theorem 1 (Noninterference). ∀c . ni(c, c).
into variable environment. Hence, variables introduced by
eval are defined in the context of the closest enclosing                Proof: The proof (detailed in the full version of this
function, or into the global object. The program is run in         paper [26]) proceeds by induction on the size of the exe-
a security context that is raised to the security label of the     cution derivation tree. As is standard, the noninterference
parsed string.                                                     theorem is uses a supporting lemma that proves freedom of
   Finally, the with statement changes the lexical environ-        public side effects under secret control. The proof includes
ment, hence shadowing existing variables, but not containing       a number of tricky sub-proofs — in particular Put, and try-
any potential variable declarations contained in the body of       catch and parts of the exception propagation. Those sub-
the with, since the variable hoisting declares the variable in     proofs have been independently stated as lemmas, and have
the variable environment.                                          been formalized and proved using the proof assistant Coq.

         IV. I NFORMATION - FLOW SECURITY AND
                    T RANSPARENCY                                  C. Transparency
   A common policy for information-flow security is nonin-            Transparency expresses that the security instrumentation
terference [11], [22]. Formally, noninterference is formulated     is conservative, i.e., if a program is able to run in the
as the preservation of a family of low-equivalence relations,      instrumented semantics, then this run is consistent with
∼, under execution. As is standard for languages with refer-       the run of the program in the original (un-instrumented)
ences [5], the family is indexed by a relation β representing      semantics. Let     denote evaluation in the un-instrumented
a bijection between the public domains of the heaps.               semantics that ignores security labels and interpret upgrade
   There are several flavors of noninterference depending on       instructions as skip. Let Φ be a function that removes all
whether timing, progress, and termination are taken into           security labels from values.
account. In the following, we consider a baseline policy           Theorem 2 (Transparency). It holds that
of termination-insensitive [44], [39] noninterference: two
expressions are considered noninterfering if all terminating        L, C ` hc, E1 i → hu̇, E2 i ⇒ Φ(C) ` hc, Φ(E1 )i          hΦ(u̇), Φ(E2 )i
runs agree on public outcomes. Termination-insensitive non-
                                                                                               V. S CENARIOS
interference allows leaks of information via the termination
behavior of programs. In a batch-job setting, it allows leaks        This section presents the implementation of the two
of at most one bit of information. Termination-insensitive         scenarios of Section III.
A. Online advertisement                                                    upg struct ( ul . childNodes ) ;
                                                                           upg ( u l . c h i l d N o d e s . l e n g t h ) ;
   Consider an online shopping cart holding a number of                    upg ( u l . l a s t C h i l d ) ;
items. The cart contains a number of items, displaying their               upg ( I 2 . n e x t S i b l i n g ) ; upg (D . n e x t S i b l i n g ) ;
name and their prices, and the total price. In addition, the               upg (D . p r e v S i b l i n g ) ; upg (D . p a r e n t ) ;
merchant wants to include ads from cooperating third parties               As discussed in Section II such upgrade sequences can be
and discounts mixed in with the items to get the information               generated by automatic testing. Finally, we add the last node,
as close to the relevant item.                                             the total, top . appendChild(T); .
                                      The resulting situation                 With some of the edges suppressed for clarity, the result
                                   is that items, discounts                of the program is the node hierarchy depicted below. Note
                                   and third party code are                how the contents of I1 , I2 , D, and T are secret, and how the
                                   all mixed, when rendering               existence of the discount D is secret, indicated by the secret
                                   the cart. This gives rise               references between D and its neighbors. In the bottom is
                                   to a number of interest-                the child nodes array, where the existence of the first three
                                   ing information-flow issues.            indices is public, and the existence of the last two is secret,
Figure 1. Shopping Cart Example    For instance, the customer              i.e. there exists a point in the array dividing the array into
                                   may want to keep the ex-                a public left part and a secret right part. The type of this
istence of certain items, their prices, or the number of                   array corresponds to the structural restrictions imposed by
items secret. Similarly, the merchant may want to keep                     Russo et al. [37]. It is interesting to note how this demand
any discounts or offers secret, as they reflect a particular               arises naturally in the implementation without imposing any
customer relationship.                                                     restrictions, but rather based on how the array is used by
   In order to construct the above example we have imple-                  the node insertion code. Note that this applies only to the
mented the core structure of DOM nodes, faithfully imple-                  array, and not to the linked node structure, which has a more
menting the interface mandated by the DOM [27]. We allow                   liberal type. For instance, it is possible to reach T using the
the programmer full access to the link structure in terms                  lastChild of ul.
of parent, firstChild, lastChild, prevSibling, nextSibling, and
the childNodes array. Insertion and removal of nodes is                                                               ulL
provided via insertBefore, appendChild, replaceChild, and
removeChild. As mandated by the recommendations [27],
repeated insertion of the same node will move the node in                                      L               L               H               H
the structure.                                                                        AL              I1H             I2H             DH              TH
   The cart is implemented using the structure of an un-
ordered list. This produces a linked structure mixing public
and secret data, and where the existence of certain elements                         0L : r1L 1L : r2L 2L : r3L 3H : r4H 4H : r5H
might be secret, depending on the security policies of the
merchant and the customer. Assume that the nodes of the                       Thus, we have shown how the language of this paper can
example ul, A, I1, I2, D, and T have been created and                      be used to encode the core of the DOM, with the basic
properly initialized. The names should be interpreted as                   operations provided by DOM nodes, with high precision. In
follows: ul stands for unordered list, I for item, A for ad,               contrast to earlier work (e.g., [37]) this is achieved entirely
D for discount and T for total.                                            without taking any DOM-specific information into account.
   Assuming that the customer wants to protect the price of                Everything, including the arrays, has been implemented in
the items and the total price, but not the items themselves,               the language, and obey the basic type rules of the system.
and that the merchant wants to protect the existence of                    We are, in a natural way, able to freely traverse the resulting
discount, we can build the list of the cart by successive use              hierarchy and access nodes via the childNodes array.
of appendChild on ul.
u l . a p p e n d C h i l d (A ) ; u l . a p p e n d C h i l d ( I 1 ) ;   B. User tracking
ul . appendChild ( I2 ) ; . . .
                                                                              Consider a login system combining the use of a shared
This code adds the ad, and the first items to the list.                    secret and the use of a username and password. Once the
Thereafter, the discount is added under secret control using               latter has been presented, a nine-digit keypad and a challenge
the expression if (h) top . appendChild(D);, where h = 1H . This           are presented. To authenticate, the user finds the correct
addition is not allowed without changing the security labels               response to the challenge using the shared secret, and uses
of the existing structure, since it is being written into under            the keypad, to enter the response. Such a system is currently
secret control. The following sequence of label upgrades                   employed by barclays.es using a response size of 2 decimal
covers the footprint of the appendChild method.                            digits chosen from a shared secret of 100 such numbers.
At the same time the page uses Google Analytics to track           the top. In the example this would allow deduction of the
usage.                                                             shared secret from the event data sent to the heat map
                         Now assume, that the above is part        generator.
                      of a bigger website, where some tech-        Propagation of secrets: corresponds to the situation, where
                      nology for generating click heat maps is     the second fire event method is used to inject the event.
                      applied. In such a case, it is very impor-   This handler upgrades the security label of the data of the
                      tant that the position information of the    event, i.e., the position of the click. This makes the event
                      clicks on the keypad is not propagated       data secret. Even though the event is propagated upwards,
                      to the heap map generator, since the         any operation on the event data will reflect its secrecy, and
                      positions of the clicks give away parts      if data reaches the heat map generator it will not be able to
Figure 2. Keypad      of the shared secret. Further, one might     use the data without triggering a security violation. Hence,
Example               want to protect not only the position        the map generator gets to know the existence of the event,
                      information in the click events, but also    but not its contents.
the fact that the clicks occur. The reasons for this might         Stopped propagation of secrets: If we want to prohibit the
include secrecy of the length of the response, or secrecy of       heat map generator from receiving click events from the
the time at which the events occur.                                keypad altogether, we have two options. The first option is
   We support the example by implementing a program                to install a non-propagating handler in k, (or all of 1 to 9)
modeling rudimentary support for event propagation. With-          that stops the propagation of events upwards to the parent. In
out loss of generality, the model only supports one event          such case, events originating from 1 to 9 will be propagated
listener per node, and one type of events. An extension            to k, where the handler will return false preventing further
to multiple event listeners and events is immediate, but           propagation which stops the event from reaching the heap
clutters the model. Each node provides methods for setting         map generator.
the event listener, setting the parent and firing an event.        Secret propagation: The other method allows the prevention
The fire event method takes a parameter, the event data,           of click events originating from 1 to 9 from being used by
and calls the registered event listener, if one exists. If the     the heat map generation without installing special handlers
event listener returns true the event is propagated to the         in k. Instead, if the third fire event method is used, the
parent otherwise not. Three different fire event methods are       event handlers, including the heap map generator, will be
provided: one acting as previously described, one upgrading        executed under secret control. The result is that the heat
the event data to secret, and one running the event handler        map generator is prevented from causing public side effects,
under secret control. The second fire event method models          and thus neither the event data or the fact that the event
events where the data is secret, e.g., the position data of        occurred can be used without causing a security violation.
the clicks discussed above, and the third models when both         This method is preferable, since it relies on the security
the data and the existence of the clicks is secret. In the         labels, rather than the presence of a special handler.
following, consider the events to be the onClick events
generated when the user click on the buttons of the keypad.           We have shown how a rudimentary event model can be
                                    Simplified, the above exam-    encoded natively in the language, and how the features
                                    ple can be represented with    provide the possibility of dynamic event propagation hierar-
                 d       map        the following DOM node         chies, in addition to both protecting the data of events, and
                                    hierarchy, where the nodes     the fact that the event occurred. The event implementation
           k            r           1 to 9 represents the but-     can be seen as a simplified version of the event model of
                                    tons grouped under a key-      Rafnsson and Sabelfeld [34], which extends the reactive
                                    pad node k, which is part      model presented by Bohannon et al. [8].
  1        5        9               of the document d, together
                                    with the rest of the docu-                        VI. R ELATED WORK
ment r, and the click heat map generator map.
   The hierarchy also represents the parent hierarchy of event        Amongst a large body of research on language-based
propagation, i.e., events on 1 are propagated to k, and finally    approach to information-flow security [39], we discuss most
to d, where the event is collected by the click heat map           related work on dynamic information control, as well as
generator, if the handlers do not stop propagation. Now            related work that targets securing JavaScript.
consider the following different possibilities.                       Dynamic information-flow control Our paper pushes the
Unconstrained propagation: corresponds to the situation            limits of dynamic information-flow enforcement on both
described above, where an event is injected using the first        expressiveness of the underlying language and on the per-
fire event method and is propagated upwards in the parent          missiveness of the enforcement. We briefly discuss previous
hierarchy after execution of the local handler until reaching      work that serves as our starting point.
You can also read