tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

index.rst (12446B)


      1 Script Security
      2 ===============
      3 
      4 .. container:: summary
      5 
      6   This page provides an overview of the script security architecture in
      7   Gecko.
      8 
      9 Like any web browser, Gecko can load JavaScript from untrusted and
     10 potentially hostile web pages and run it on the user's computer. The
     11 security model for web content is based on the `same-origin policy
     12 <https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy>`__,
     13 in which code
     14 gets full access to objects from its origin but highly restricted access
     15 to objects from a different origin. The rules for determining whether an
     16 object is same-origin with another, and what access is allowed
     17 cross-origin, are now mostly standardized across browsers.
     18 
     19 Gecko has an additional problem, though: while its core is written in
     20 C++, the front-end code is written in JavaScript. This JavaScript code,
     21 which is commonly referred to as c\ *hrome code*, runs with system
     22 privileges. If the code is compromised, the attacker can take over the
     23 user's computer. Legacy SDK extensions also run with chrome privileges.
     24 
     25 Having the browser front end in JavaScript has benefits: it can be much
     26 quicker to develop in JavaScript than in C++, and contributors do not
     27 need to learn C++. However, JavaScript is a highly dynamic, malleable
     28 language, and without help it's difficult to write system-privileged
     29 code that interacts safely with untrusted web content. From the point of
     30 view of chrome code, the script security model in Gecko is intended to
     31 provide that help to make writing secure, system-privileged JavaScript a
     32 realistic expectation.
     33 
     34 .. _Security_policy:
     35 
     36 Security policy
     37 ---------------
     38 
     39 Gecko implements the following security policy:
     40 
     41 -  **Objects that are same-origin** are able to access each other
     42   freely. For example, the objects associated with a document served
     43   from *https://example.org/* can access each other, and they can also
     44   access objects served from *https://example.org/foo*.
     45 -  **Objects that are cross-origin** get highly restricted access to
     46   each other, according to the same-origin policy.
     47   For example, code served from *https://example.org/* trying to access
     48   objects from *https://somewhere-else.org/* will have restricted
     49   access.
     50 -  **Objects in a privileged scope** are allowed complete access to
     51   objects in a less privileged scope, but by default they see a
     52   `restricted view <#privileged-to-unprivileged-code>`__
     53   of such objects, designed to prevent them from being tricked by the
     54   untrusted code. An example of this scope is chrome-privileged
     55   JavaScript accessing web content.
     56 -  **Objects in a less privileged scope** don't get any access to
     57   objects in a more privileged scope, unless the more privileged scope
     58   `explicitly clones those objects <#unprivileged-to-privileged-code>`__.
     59   An example of this scope is web content accessing objects in a
     60   chrome-privileged scope.
     61 
     62 .. _Compartments:
     63 
     64 Compartments
     65 ------------
     66 
     67 Compartments are the foundation for Gecko's script security
     68 architecture. A compartment is a specific, separate area of memory. In
     69 Gecko, there's a separate compartment for every global object. This
     70 means that each global object and the objects associated with it live in
     71 their own region of memory.
     72 
     73 .. image:: images/compartments.png
     74 
     75 Normal content windows are globals, of course, but so are chrome
     76 windows, sandboxes, workers, the ``ContentFrameMessageManager`` in a frame
     77 script, and so on.
     78 
     79 Gecko guarantees that JavaScript code running in a given compartment is
     80 only allowed to access objects in the same compartment. When code from
     81 compartment A tries to access an object in compartment B, Gecko gives it
     82 a *cross-compartment wrapper*. This is a proxy in compartment A for the
     83 real object, which lives in compartment B.
     84 
     85 .. image:: images/cross-compartment-wrapper.png
     86 
     87 Inside the same compartment, all objects share a global and are
     88 therefore same-origin with each other. Therefore there's no need for any
     89 security checks, there are no wrappers, and there is no performance
     90 overhead for the common case of objects in a single window interacting
     91 with each other.
     92 
     93 Whenever cross-compartment access happens, the wrappers enable us to
     94 implement the appropriate security policy. Because the wrapper we choose
     95 is specific to the relationship between the two compartments, the
     96 security policy it implements can be static: when the caller uses the
     97 wrapper, there's no need to check who is making the call or where it is
     98 going.
     99 
    100 .. _Cross-compartment_access:
    101 
    102 Cross-compartment access
    103 ------------------------
    104 
    105 .. _Same-origin:
    106 
    107 Same-origin
    108 ~~~~~~~~~~~
    109 
    110 As we've already seen, the most common scenario for same-origin access
    111 is when objects belonging to the same window object interact. This all
    112 takes place within the same compartment, with no need for security
    113 checks or wrappers.
    114 
    115 When objects share an origin but not a global - for example two web
    116 pages from the same protocol, port, and domain - they belong to two
    117 different compartments, and the caller gets a *transparent wrapper* to
    118 the target object.
    119 
    120 .. image:: images/same-origin-wrapper.png
    121 
    122 Transparent wrappers allow access to all the target's properties:
    123 functionally, it's as if the target is in the caller's compartment.
    124 
    125 .. _Cross-origin:
    126 
    127 Cross-origin
    128 ~~~~~~~~~~~~
    129 
    130 If the two compartments are cross-origin, the caller gets a
    131 *cross-origin wrapper*.
    132 
    133 .. image:: images/cross-origin-wrapper.png
    134 
    135 This denies access to all the object's properties, except for a few
    136 properties of Window and Location objects, as defined by
    137 the `same-origin
    138 policy <https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#cross-origin_script_api_access>`__.
    139 
    140 .. _Privileged_to_unprivileged_code:
    141 
    142 Privileged to unprivileged code
    143 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    144 
    145 The most obvious example of this kind of security relation is between
    146 system-privileged chrome code and untrusted web content, but there are
    147 other examples in Gecko. The Add-on SDK runs content scripts in
    148 sandboxes, which are initialized with an `expanded
    149 principal <#expanded-principal>`__,
    150 giving them elevated privileges with respect to the web content they
    151 operate on, but reduced privileges with respect to chrome.
    152 
    153 If the caller has a higher privilege than the target object, the caller
    154 gets an *Xray wrapper* for the object.
    155 
    156 .. image:: images/xray-wrapper.png
    157 
    158 Xrays are designed to prevent untrusted code from confusing trusted code
    159 by redefining objects in unexpected ways. For example, privileged code
    160 using an Xray to a DOM object sees only the original version of the DOM
    161 object. Any expando properties are not visible, and if any native DOM properties have been
    162 redefined, they are not visible in the Xray.
    163 
    164 The privileged code is able to waive Xrays if it wants unfiltered access to the untrusted object.
    165 
    166 See `Xray vision <xray_vision.html>`__ for much more information on Xrays.
    167 
    168 .. _Unprivileged_to_privileged_code:
    169 
    170 Unprivileged to privileged code
    171 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    172 
    173 If the caller has lower privileges than the target object, then the
    174 caller gets an *opaque wrapper.*
    175 
    176 .. image:: images/opaque-wrapper.png
    177 
    178 An opaque wrapper denies all access to the target object.
    179 
    180 However, the privileged target is able to copy objects and functions
    181 into the less privileged scope using the ``exportFunction()`` and
    182 ``cloneInto()`` functions, and the less privileged scope is then able
    183 to use them.
    184 
    185 .. _Security_checks:
    186 
    187 Security checks
    188 ---------------
    189 
    190 To determine the security relation between two compartments, Gecko uses
    191 two concepts: *security principals* and the act of *subsuming*. To
    192 establish the security relationship between two compartments A and B,
    193 Gecko asks:
    194 
    195 *Does the security principal for compartment A subsume the security
    196 principal for compartment B, and vice versa?*
    197 
    198 .. _Subsumes:
    199 
    200 Subsumes
    201 ~~~~~~~~
    202 
    203 +-----------------------------------+-----------------------------------+
    204 | *A subsumes B*                    | A has all of the privileges of B, |
    205 |                                   | and possibly more, and therefore  |
    206 |                                   | A is allowed to see and do        |
    207 |                                   | anything that B can see and do.   |
    208 +-----------------------------------+-----------------------------------+
    209 | *A Subsumes B &&* *B Subsumes A*  | A and B are same-origin.          |
    210 +-----------------------------------+-----------------------------------+
    211 | *A Subsumes B && B !Subsumes A*   | A is more privileged than B.      |
    212 |                                   |                                   |
    213 |                                   | A gets access to all of B, by     |
    214 |                                   | default with Xray vision, which   |
    215 |                                   | it may choose to waive.           |
    216 |                                   |                                   |
    217 |                                   | B gets no access to A, although A |
    218 |                                   | may choose to export objects to   |
    219 |                                   | B.                                |
    220 +-----------------------------------+-----------------------------------+
    221 | *A !Subsumes B && B !Subsumes A*  | A and B are cross-origin.         |
    222 +-----------------------------------+-----------------------------------+
    223 
    224 .. _Security_principals:
    225 
    226 Security principals
    227 ~~~~~~~~~~~~~~~~~~~
    228 
    229 There are four types of security principal: the system principal,
    230 content principals, expanded principals, and the null principal.
    231 
    232 .. _System_principal:
    233 
    234 System principal
    235 ^^^^^^^^^^^^^^^^
    236 
    237 The system principal passes all security checks. It subsumes itself and
    238 all other principals. Chrome code, by definition, runs with the system
    239 principal, as do frame scripts.
    240 
    241 .. _Content_principal:
    242 
    243 Content principal
    244 ^^^^^^^^^^^^^^^^^
    245 
    246 A content principal is associated with some web content and is defined
    247 by the origin
    248 of the content. For example, a normal DOM window has a content principal
    249 defined by the window's origin. A content principal subsumes only other
    250 content principals with the same origin. It is subsumed by the system
    251 principal, any expanded principals that include its origin, and any
    252 other content principals with the same origin.
    253 
    254 .. _Expanded_principal:
    255 
    256 Expanded principal
    257 ^^^^^^^^^^^^^^^^^^
    258 
    259 An expanded principal is specified as an array of origins:
    260 
    261 .. code:: JavaScript
    262 
    263   ["http://mozilla.org", "http://moz.org"]
    264 
    265 The expanded principal subsumes every content principal it contains. The
    266 content principals do not subsume the expanded principal, even if the
    267 expanded principal only contains a single content principal.
    268 
    269 Thus ``["http://moz.org"]`` subsumes ``"http://moz.org"`` but not vice
    270 versa. The expanded principal gets full access to the content principals
    271 it contains, with Xray vision by default, and the content principals get
    272 no access to the expanded principal.
    273 
    274 This also enables the script security model to treat compartments that
    275 have expanded principals more like part of the browser than like web
    276 content. This means, for example, that it can run when JavaScript is
    277 disabled for web content.
    278 
    279 Expanded principals are useful when you want to give code extra
    280 privileges, including cross-origin access, but don't want to give the
    281 code full system privileges. For example, expanded principals are used
    282 in the Add-on SDK to give content scripts cross-domain privileges for a predefined set of
    283 domains,
    284 and to protect content scripts from access by untrusted web content,
    285 without having to give content scripts system privileges.
    286 
    287 .. _Null_principal:
    288 
    289 Null principal
    290 ^^^^^^^^^^^^^^
    291 
    292 The null principal fails almost all security checks. It has no
    293 privileges and can't be accessed by anything but itself and chrome. It
    294 subsumes no other principals, even other null principals. (This is what
    295 is used when HTML5 and other specs say "origin is a globally unique
    296 identifier".)
    297 
    298 .. _Principal_relationships:
    299 
    300 Principal relationships
    301 ~~~~~~~~~~~~~~~~~~~~~~~
    302 
    303 The diagram below summarizes the relationships between the different
    304 principals. The arrow connecting principals A and B means "A subsumes
    305 B". (A is the start of the arrow, and B is the end.)
    306 
    307 .. image:: images/principal-relationships.png
    308 
    309 .. _Computing_a_wrapper:
    310 
    311 Computing a wrapper
    312 -------------------
    313 
    314 The following diagram shows the factors that determine the kind of
    315 wrapper that compartment A would get when trying to access an object in
    316 compartment B.
    317 
    318 .. image:: images/computing-a-wrapper.png