diff options
Diffstat (limited to 'files/ru/xpcnativewrapper')
-rw-r--r-- | files/ru/xpcnativewrapper/index.html | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/files/ru/xpcnativewrapper/index.html b/files/ru/xpcnativewrapper/index.html new file mode 100644 index 0000000000..c12a434e12 --- /dev/null +++ b/files/ru/xpcnativewrapper/index.html @@ -0,0 +1,108 @@ +--- +title: XPCNativeWrapper +slug: XPCNativeWrapper +tags: + - DOM + - XPCNativeWrapper + - Безопасность + - Расширения +--- +<p> </p> +<p><code>XPCNativeWrapper</code> позволяет так обернуть объект, чтобы доступ к нему был <a href="/en/Safely_accessing_content_DOM_from_chrome">безопасен для привилегированного кода</a>. Эта обёртка может быть использована во всех версиях, хотя её поведение слегка изменилось начиная с <span>Firefox 1.5</span> (<span>Gecko 1.8</span>). Информацию о поведении <code>XPCNativeWrapper</code> в <span>Firefox</span> версий младше 1.5 можно получить из <a class="external" href="http://kb.mozillazine.org/XPCNativeWrapper">статьи о <code>XPCNativeWrapper</code> в <span>MozillaZine KnowledgeBase</span></a>. Эта же статья посвящена <code>XPCNativeWrapper</code> в <span>Firefox</span> версий 1.5 и выше.</p> +<h3 id=".D0.A7.D1.82.D0.BE_.D0.B4.D0.B5.D0.BB.D0.B0.D0.B5.D1.82_XPCNativeWrapper" name=".D0.A7.D1.82.D0.BE_.D0.B4.D0.B5.D0.BB.D0.B0.D0.B5.D1.82_XPCNativeWrapper">Что делает <code>XPCNativeWrapper</code></h3> +<p>An <code>XPCNativeWrapper</code> limits access to the properties and methods of the object it wraps. The only properties and methods accessible through an <code>XPCNativeWrapper</code> are those that are defined in IDL or defined by DOM Level 0 (though some DOM Level 0 properties and methods <a href="#Limitations_of_XPCNativeWrapper">do not work on an <code>XPCNativeWrapper</code></a>). In particular, properties added to an object via JavaScript are not exposed by an <code>XPCNativeWrapper</code> for this object, and nor are getters and setters defined with <code>__defineGetter__</code> and <code>__defineSetter__</code>. The intent is to allow safe access to the IDL-defined methods of the object.</p> +<p>Please make sure to read the <a href="#Known_Bugs">known bugs</a> section, especially when writing code targeted at a range of 1.5.0.x Firefox releases.</p> +<h3 id=".D0.A2.D0.B8.D0.BF.D1.8B_XPCNativeWrapper" name=".D0.A2.D0.B8.D0.BF.D1.8B_XPCNativeWrapper">Типы <code>XPCNativeWrapper</code></h3> +<p>There are three different types of <code>XPCNativeWrapper</code> in Firefox 1.5. All three types wrap a possibly-unsafe object and <a href="#What_XPCNativeWrapper_does">provide safe access to its properties and methods</a>.</p> +<p>The differences in behavior between the three types of <code>XPCNativeWrapper</code> are determined by two characteristics an <code>XPCNativeWrapper</code> wrapper can have. An <code>XPCNativeWrapper</code> can be <a href="#Explicit_vs._Implicit"><em>explicit</em></a> (or the opposite, <em>implicit</em>) and can be <a href="#Deep_vs._Shallow"><em>deep</em></a> (or the opposite, <em>shallow</em>). The type of wrapper created is determined by <a href="#Creating_XPCNativeWrapper_objects">the way it was created</a> as follows:</p> +<table> <tbody> <tr> <th>Created by</th> <th>Explicit/Implicit</th> <th>Deep/Shallow</th> </tr> <tr> <th><a href="#Protected_script_accessing_an_untrusted_object">Protected script accessing an untrusted object</a></th> <td>Implicit</td> <td>Deep</td> </tr> <tr> <th><a href="#XPCNativeWrapper_constructor_call_with_string_arguments">Constructor called with string arguments</a></th> <td>Explicit</td> <td>Shallow</td> </tr> <tr> <th><a href="#XPCNativeWrapper_constructor_call_with_no_string_arguments">Constructor called with no string arguments</a></th> <td>Explicit</td> <td>Deep</td> </tr> </tbody> +</table> +<h4 id="Explicit_vs._Implicit" name="Explicit_vs._Implicit">Explicit vs. Implicit</h4> +<p>The difference in behavior between explicit and implicit <code>XPCNativeWrapper</code> is that a property access on an implicit <code>XPCNativeWrapper</code> from script that is not <a href="#What_is_a_protected_script.3F">protected</a> is NOT safe. The property access will be forwarded through to the <code>wrappedJSObject</code> of the <code>XPCNativeWrapper</code>.</p> +<p>This means that scripts that are not <a href="#What_is_a_protected_script.3F">protected</a> don't need to worry about bugs arising because other code hands them an implicit <code>XPCNativeWrapper</code>. On the other hand, such scripts do need to watch out for unsafe object access.</p> +<p>Property access on an explicit <code>XPCNativeWrapper</code> is safe no matter whether the caller is <a href="#What_is_a_protected_script.3F">protected</a>.</p> +<h4 id="Deep_vs._Shallow" name="Deep_vs._Shallow">Deep vs. Shallow</h4> +<p>The difference in behavior between deep and shallow <code>XPCNativeWrapper</code> is that when a property is accessed or a function is called on a deep wrapper the return value will be wrapped in a <code>XPCNativeWrapper</code> of its own. The new <code>XPCNativeWrapper</code> will also be deep and it will be <a href="#Explicit_vs._Implicit">explicit</a> if and only if the <code>XPCNativeWrapper</code> whose property is accessed was explicit. By contrast, when a property is accessed or a function is called on a shallow wrapper, the return value may be an unsafe object.</p> +<p>For example, say we are given three instances of <code>XPCNativeWrapper</code> for the same window object. Let us call them <code>deepExplicitWindow</code>, <code>deepImplicitWindow</code> and <code>shallowWindow</code>. Then we have:</p> +<pre class="eval">var doc1 = deepExplicitWindow.document; +// doc1 is now a deep explicit <code>XPCNativeWrapper</code> for +// the document object. Accessing doc1.open(), say, is safe. +</pre> +<pre class="eval">var doc2 = deepImplicitWindow.document; +// If the caller has xpcnativewrappers=yes set, doc2 is now a deep +// implicit <code>XPCNativeWrapper</code> for the document object. +// Otherwise doc2 is now the unsafe document object, since the +// property access was simply passed along to the unsafe window object. +</pre> +<pre class="eval">var doc3 = shallowWindow.document; +// doc3 is now the unsafe document object. +</pre> +<h3 id=".D0.A1.D0.BE.D0.B7.D0.B4.D0.B0.D0.BD.D0.B8.D0.B5_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2_XPCNativeWrapper" name=".D0.A1.D0.BE.D0.B7.D0.B4.D0.B0.D0.BD.D0.B8.D0.B5_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2_XPCNativeWrapper">Создание объектов <code>XPCNativeWrapper</code></h3> +<p>Существует три различных способа создания объекта <code>XPCNativeWrapper</code>; по одному способу на каждый из трёх типов.</p> +<h4 id="Protected_script_accessing_an_untrusted_object" name="Protected_script_accessing_an_untrusted_object">Protected script accessing an untrusted object</h4> +<p>Any time a <a href="#What_is_a_protected_script.3F">protected script</a> accesses an <a href="#What_is_an_untrusted_object.3F">untrusted object</a> it will get back an <a href="#Explicit_vs._Implicit">implicit</a> <a href="#Deep_vs._Shallow">deep</a> <code>XPCNativeWrapper</code>. Accessing properties of this <code>XPCNativeWrapper</code> is safe from <a href="#What_is_a_protected_script.3F">protected scripts</a>.</p> +<p>A wrapper created in this way will stick around as long as the object being wrapped does and accessing an object twice in a row will give the same <code>XPCNativeWrapper</code>.</p> +<h5 id="What_is_a_protected_script.3F" name="What_is_a_protected_script.3F">What is a protected script?</h5> +<p>In Firefox versions 1.5 through 1.5.0.5, a script is protected or not protected based solely on its URI. A script is protected only if its URI starts with a known protected prefix; scripts not loaded by URI (e.g. JavaScript-implemented components) are not protected. The protected prefixes in Firefox 1.5 are determined by the Chrome Registry.</p> +<p>By default, <strong>all content packages are protected</strong>. This means that all URIs that start "<code>chrome://<package name>/content/</code>" (for any package) are protected. Individual packages can <a href="/ru/Chrome_Registration#xpcnativewrappers" title="ru/Chrome_Registration#xpcnativewrappers">override this using a flag</a> in their chrome manifest file.</p> +<p>Starting with Firefox 1.5.0.6, JavaScript-implemented components are protected scripts. So a script is protected if it's either loaded from a URI which starts with a protected prefix or is a JavaScript-implemented component.</p> +<h5 id="What_is_an_untrusted_object.3F" name="What_is_an_untrusted_object.3F">What is an untrusted object?</h5> +<p>All objects are either trusted or untrusted. An object is trusted if any of the following hold:</p> +<ol> <li>Its parent (<code>__parent__</code> property in JavaScript) is a trusted object.</li> <li>It is the root scope object for a JavaScript component.</li> <li>It is the window object for a <a href="#What_is_a_trusted_window.3F">trusted window</a>.</li> +</ol> +<p>Since all DOM objects in a window have the window on their <code>__parent__</code> chain, they will be trusted if and only if their window is trusted.</p> +<h5 id="What_is_a_trusted_window.3F" name="What_is_a_trusted_window.3F">What is a trusted window?</h5> +<p>Whether a window is trusted depends on its container. A window is trusted if any of the following holds:</p> +<ol> <li>It is a top-level window (e.g. <code><xul:window></code>, <code><xul:dialog></code>, or some URI passed to the <code>-chrome</code> command-line flag).</li> <li>Its parent is trusted, and one of the following three options holds: <ol> <li>It is not loaded in a <code><xul:iframe></code> or <code><xul:browser></code>.</li> <li>The <code><xul:iframe></code> or <code><xul:browser></code> loading it doesn't have a "type" attribute.</li> <li>The value of the "type" attribute of the <code><xul:iframe></code> or <code><xul:browser></code> loading it is not "content" and does not start with "content-".</li> </ol> </li> +</ol> +<p>Note that whether a window is trusted does <strong>not</strong> depend on the URI loaded in the window. So for example, the following would create trusted windows when used inside a document whose window is already trusted:</p> +<ul> <li><code><xul:browser></code></li> <li><code><xul:browser type="chrome"></code></li> <li><code><xul:browser type="rabid_dog"></code></li> <li><code><xul:iframe type="foofy"></code></li> <li><code><html:iframe></code></li> <li><code><html:iframe type="content"></code></li> +</ul> +<p>The following would not create trusted windows:</p> +<ul> <li><code><xul:browser type="content"></code></li> <li><code><xul:iframe type="content-primary"></code></li> +</ul> +<p>Further note that any child window of an untrusted window is automatically untrusted.</p> +<h5 id="What_happens_when_a_script_accesses_an_object.3F" name="What_happens_when_a_script_accesses_an_object.3F">What happens when a script accesses an object?</h5> +<p>The table below describes what happens when a script accesses an object, and how the wrapper is involved.</p> +<table> <tbody> <tr> <th>Script</th> <th>Object</th> <th>Effects</th> </tr> <tr> <td>Protected</td> <td>Trusted</td> <td>No wrapper is created and therefore the script gets full access to the object.</td> </tr> <tr> <td>Protected</td> <td>Untrusted</td> <td>An <a href="#Explicit_vs._Implicit">implicit</a> <a href="#Deep_vs._Shallow">deep</a> <code>XPCNativeWrapper</code> is created.</td> </tr> <tr> <td>Unprotected</td> <td>Trusted</td> <td>No wrapper is created, just as in the protected/trusted case.</td> </tr> <tr> <td>Unprotected</td> <td>Untrusted</td> <td>No wrapper is created, just as in the protected/trusted case.</td> </tr> </tbody> +</table> +<h4 id="XPCNativeWrapper_constructor_call_with_string_arguments" name="XPCNativeWrapper_constructor_call_with_string_arguments"><code>XPCNativeWrapper</code> constructor call with string arguments</h4> +<p>For example:</p> +<pre class="eval">var contentWinWrapper = new XPCNativeWrapper(content, + "document"); +</pre> +<p>This creates an <a href="#Explicit_vs._Implicit">explicit</a> <a href="#Deep_vs._Shallow">shallow</a> <code>XPCNativeWrapper</code>. This syntax has been kept for compatibility with versions prior to Firefox 1.5. While all properties of the <code>contentWinWrapper</code> object can now be safely accessed, the return values of these properties are NOT safe to access (just like in versions prior to Firefox 1.5), since the <code>XPCNativeWrapper</code> is <a href="#Deep_vs._Shallow">shallow</a>. So to compare the content document title to the current content selection, one must do:</p> +<pre class="eval">var winWrapper = new XPCNativeWrapper(content, "document", + "getSelection()"); +var docWrapper = new XPCNativeWrapper(winWrapper.document, + "title"); +return docWrapper.title == winWrapper.getSelection(); +</pre> +<p>just like in versions before Firefox 1.5. Note that the <code>"getSelection()"</code> argument is not strictly needed here; if the code is not intended for use with Firefox versions before 1.5 it can be removed. A single string argument after the object being wrapped is all that is required for Firefox 1.5 to create this type of <code>XPCNativeWrapper</code>.</p> +<h4 id="XPCNativeWrapper_constructor_call_with_no_string_arguments" name="XPCNativeWrapper_constructor_call_with_no_string_arguments"><code>XPCNativeWrapper</code> constructor call with no string arguments</h4> +<p>For example:</p> +<pre class="eval">var contentWinWrapper = new XPCNativeWrapper(content); +</pre> +<p>This creates an <a href="#Explicit_vs._Implicit">explicit</a> <a href="#Deep_vs._Shallow">deep</a> <code>XPCNativeWrapper</code>. Accessing properties of this <code>XPCNativeWrapper</code> is safe, and the return values will also be wrapped in <a href="#Explicit_vs._Implicit">explicit</a> <a href="#Deep_vs._Shallow">deep</a> <code>XPCNativeWrapper</code> objects.</p> +<h3 id="Setting_.22expando.22_properties_on_XPCNativeWrapper" name="Setting_.22expando.22_properties_on_XPCNativeWrapper">Setting "expando" properties on <code>XPCNativeWrapper</code></h3> +<p>It is possible to set "expando" properties (properties with names that don't correspond to IDL-defined properties) on <code>XPCNativeWrapper</code> objects. If this is done, then chrome will be able to see these expando properties, but content will not be able to. <strong>There is no safe way to set an expando property from chrome and have it be readable from content.</strong></p> +<h3 id="XPCNativeWrapper_lifetime" name="XPCNativeWrapper_lifetime"><code>XPCNativeWrapper</code> lifetime</h3> +<p>Explicit <code>XPCNativeWrapper</code> objects exist while they are referenced. Creating a new explicit <code>XPCNativeWrapper</code> for the same possibly-unsafe object will create a new wrapper object; something to watch out for when <a href="#Setting_.22expando.22_properties_on_XPCNativeWrapper">setting "expando" properties</a></p> +<p>Implicit <code>XPCNativeWrapper</code> objects have the same lifetime as the object they're wrapping.</p> +<h3 id="Accessing_unsafe_properties" name="Accessing_unsafe_properties">Accessing unsafe properties</h3> +<p>If unsafe access to a property is required for some reason, this can be accomplished via the <code>wrappedJSObject</code> property of the wrapper. For example, if <code>docWrapper</code> is a wrapper for <code>doc</code>, then</p> +<pre class="eval">docWrapper.wrappedJSObject.prop +</pre> +<p>is the same as</p> +<pre class="eval">doc.prop +</pre> +<h3 id=".D0.98.D0.B7.D0.B2.D0.B5.D1.81.D1.82.D0.BD.D1.8B.D0.B5_.D0.BE.D1.88.D0.B8.D0.B1.D0.BA.D0.B8" name=".D0.98.D0.B7.D0.B2.D0.B5.D1.81.D1.82.D0.BD.D1.8B.D0.B5_.D0.BE.D1.88.D0.B8.D0.B1.D0.BA.D0.B8">Известные ошибки</h3> +<p>Известны две ошибки реализации <code>XPCNativeWrapper</code> в версиях 1.5.0.x:</p> +<ol> <li>Firefox с версии 1.5 по версию 1.5.0.4 содержит {{ Bug(337095) }}, в результате чего в некоторых случаях для защищённых скриптов не создаются обёртки. А именно, если из защищённого скрипта происходит обращение к свойству или вызов функции, которые возвращают недоверенный (<span>untrusted</span>) объект, обёртка будет создана. Однако, если функция в защищённом скрипте вызывается из C++, и в качестве аргумента этой функции передаётся недоверенный объект, обёртка <em>не</em> будет создана. Поэтому функции, которые могут быть вызваны подобным образом, <a href="#XPCNativeWrapper_constructor_call_with_no_string_arguments">должны сами производить обёртывание</a>. Эта ошибка исправлена в Firefox версии 1.5.0.5 и выше.</li> <li>Firefox с версии 1.5 по версию 1.5.0.5 содержит {{ Bug(345991) }}, в результате чего компоненты написанные на JavaScript не могут быть защищёнными скриптами. Эта ошибка исправлена в Firefox версии 1.5.0.6 и выше.</li> +</ol> +<h3 id="Limitations_of_XPCNativeWrapper" name="Limitations_of_XPCNativeWrapper">Limitations of <code>XPCNativeWrapper</code></h3> +<p>There are some commonly used properties and coding styles that cannot be used with <code>XPCNativeWrapper</code>. Specifically:</p> +<ol> <li>Assigning to or reading an <code>on*</code> property on an <code>XPCNativeWrapper</code> of a DOM node or Window object will throw an exception. (Use addEventListener instead, and use "event.preventDefault();" in your handler if you used "return false;" before.)</li> <li>Access to frames by window name (e.g. <code>window.frameName</code>) does not work on an <code>XPCNativeWrapper</code></li> <li><code>document.all</code> does not work on an <code>XPCNativeWrapper</code> for a document.</li> <li>Access to named items by name does not work on an <code>XPCNativeWrapper</code> for an HTML document. For example, if you have a <code><form name="foo"></code> and <code>docWrapper</code> is a wrapper for the HTML document <code>doc</code> then <code>doc.foo</code> is an <code>HTMLFormElement</code> while <code>docWrapper.foo</code> is <code>undefined</code>. Code that wishes to do this could use <code>docWrapper.forms.namedItem("foo")</code> instead.</li> <li>Access to nodes by id doesn't work on an <code>XPCNativeWrapper</code> for an HTML document. <code>getElementById</code> should be used instead.</li> <li>Access to inputs by name doesn't work on an <code>XPCNativeWrapper</code> for an HTML form. Code that wishes to do this should use <code>form.elements.namedItem("inputname")</code>.</li> <li>Access to elements by name doesn't work on an <code>XPCNativeWrapper</code> for an <code>HTMLCollection</code>. Code that wishes to do this should use the <code>namedItem()</code> method. Note that <code>namedItem</code> only returns the first input element with the name, even if there are multiple elements (e.g. radio buttons) with the same name in the form.</li> <li>Calling methods implemented by NPAPI plugins through the <code>XPCNativeWrapper</code> for the corresponding node does not work.</li> <li>Getting or setting properties implemented by NPAPI plugins though the <code>XPCNativeWrapper</code> for the corresponding node does not work.</li> <li>Calling methods implemented via XBL bindings attached to a node through an <code>XPCNativeWrapper</code> for that node does not work.</li> <li>Getting or setting properties implemented via XBL bindings attached to a node through an <code>XPCNativeWrapper</code> for that node does not work.</li> <li>Enumerating the properties of an <code>XPCNativeWrapper</code> via "<code>for (var p in wrapper)</code>" does not enumerate the IDL-defined properties.</li> <li>Object.prototype is not on the prototype chain of an <code>XPCNativeWrapper</code>. As a result, various <code>Object.prototype</code> properties are undefined on an <code>XPCNativeWrapper</code> (to be precise, these are <code>__proto__</code>, <code>__parent__</code>, <code>__count__</code>, <code>toSource</code>, <code>toLocaleString</code>, <code>valueOf</code>, <code>watch</code>, <code>unwatch</code>, <code>hasOwnProperty</code>, <code>isPrototypeOf</code>, <code>propertyIsEnumerable</code>, <code>__defineGetter__</code>, <code>__defineSetter__</code>, <code>__lookupGetter__</code>, and <code>__lookupSetter__</code>).</li> <li>There is no support for the <code>importXPCNative</code> method the old <code>XPCNativeWrapper</code> implementation used to have.</li> <li>Accessing standard classes (such as <code>Function</code>) through an XPCNativeWrapper will not work. To create functions and objects with a particular window's parent, use that window's <code>eval</code> function.</li> +</ol> +<p><a class="external" href="http://oreillynet.com/pub/a/network/2005/11/01/avoid-common-greasemonkey-pitfalls.html?page=3">Avoid Common Pitfalls in Greasemonkey</a> has an elaborate explanation for some of these limitations (in context of Greasemonkey scripts).</p> +<p>{{ languages( { "en": "en/XPCNativeWrapper", "fr": "fr/XPCNativeWrapper", "it": "it/XPCNativeWrapper" } ) }}</p> |