1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<div class="warning">The API used to gain Chrome access is currently an
experimental feature of the SDK, and may change in future releases.</div>
# Chrome Authority #
## Using Chrome Authority ##
The most powerful low-level modules are run with "chrome privileges",
which gives them access to the infamous <code>Components</code> object, which
grants unfettered access to the host system. From this, the module can do
pretty much anything the browser is capable of. To obtain these privileges,
the module must declare its intent with a statement like the following:
var {Cc, Ci} = require("chrome");
The object returned by <code>require("chrome")</code>, when unpacked with the
"destructuring assignment" feature available in the Mozilla JS environment,
will provide the usual <code>Components.*</code> aliases:
<code>**Cc**</code>
An alias for `Components.classes`.
<code>**Ci**</code>
An alias for `Components.interfaces`.
<code>**Cu**</code>
An alias for `Components.utils`.
<code>**Cr**</code>
An alias for `Components.results`.
<code>**Cm**</code>
An alias for `Components.manager`.
<code>**components**</code>
An alias for `Components` itself (note the lower-case). From this you can
access less-frequently-used properties like `Components.stack` and
`Components.isSuccessCode`.
Note: the `require("chrome")` statement is the **only** way to access chrome
functionality and the `Components` API. The `Components` object should
**not** be accessed from modules. The SDK tools will emit a warning
if it sees module code which references `Components` directly.
Your modules should refrain from using chrome privileges unless they are
absolutely necessary. Chrome-authority-using modules must receive extra
security review, and most bugs in these modules are security-critical.
## Manifest Generation ##
The **manifest** is a list, included in the generated XPI, which
specifies which modules have requested `require()` access to which other
modules. It also records which modules have requested chrome access. This
list is generated by scanning all included modules for `require(XYZ)`
statements and recording the particular "XYZ" strings that they reference.
When the manifest implementation is complete the runtime loader will actually
prevent modules from `require()`ing modules that are not listed in the
manifest. Likewise, it will prevent modules from getting chrome authority
unless the manifest indicates that they have asked for it. This will ensure
that reviewers see the same authority restrictions that are enforced upon the
running code, increasing the effectiveness of the time spent reviewing the
add-on. (until this work is complete, modules may be able to sneak around these
restrictions).
The manifest is built with a simple regexp-based scanner, not a full
Javascript parser. Developers should stick to simple `require` statements,
with a single static string, one per line of code. If the scanner fails to
see a `require` entry, the manifest will not include that entry, and (once
the implementation is complete) the runtime code will get an exception.
For example, none of the following code will be matched by the manifest
scanner, leading to exceptions at runtime, when the `require()` call is
prohibited from importing the named modules:
// all of these will fail!
var xhr = require("x"+"hr");
var modname = "xpcom";
var xpcom = require(modname);
var one = require("one"); var two = require("two");
The intention is that developers use `require()` statements for two purposes:
to declare (to security reviewers) what sorts of powers the module wants to
use, and to control how those powers are mapped into the module's local
namespace. Their statements must therefore be clear and easy to parse. A
future manifest format may move the declaration portion out to a separate
file, to allow for more fine-grained expression of authority.
Commands that build a manifest, like "`cfx xpi`" or "`cfx run`", will scan
all included modules for use of `Cc`/`Ci` aliases (or the expanded
`Components.classes` forms). It will emit a warning if it sees the expanded
forms, or if it sees a use of e.g. "`Cc`" without a corresponding entry in
the `require("chrome")` statement. These warnings will serve to guide
developers to use the correct pattern. All module developers should heed the
warnings and correct their code until the warnings go away.
|