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