Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

XPCNativeWrapper

XPCNativeWrapper è un modo di imballare un oggetto in modo da rendere sicuro l'accesso tramite un codice privilegiato. Può essere utilizzato in tutte le versioni di Firefox, anche se il comportamento è in qualche modo cambiato a partire da Firefox 1.5 (Gecko 1.8). Guarda la voce XPCNativeWrapper su MozillaZine(EN) per il comportamento di XPCNativeWrapper nelle versioni di Firefox precedenti alla 1.5. Questo articolo tratta XPCNativeWrapper solo su Firefox 1.5 o superiori.

Che cosa fa XPCNativeWrapper

Un XPCNativeWrapper limita l'accesso alle proprietà e ai metodi dell'oggetto che imballa. Le sole proprietà e metodi accessibili attraverso un XPCNativeWrapper sono quelle definite nell'IDL oppure quelle definite da un livello DOM pari a 0 (anche se alcune proprietà o metodi di livello zero non funzionano con un XPCNativeWrapper). In particolare, le proprietà aggiunte ad un oggetto con un JavaScript non sono esposte ad un XPCNativeWrapper per l'oggetto imballato, e l'accesso e la modifica non sono definibili con __defineGetter__ e __defineSetter__. L'intento è quello di permettere un accesso sicuro ai metodi definiti dall'IDL dell'oggetto.

Tipi di XPCNativeWrapper

Esistono tre diversi tipi di XPCNativeWrapper in Firefox 1.5. Tutti e tre i tipi imballano un ogetto potenzialmente non sicuro e garantiscono un accesso sicuro alle sue proprietà e metodi.

Le differenze di comportamento tra i tre tipi di XPCNativeWrapper sono determinate dalle due caratteristiche che un XPCNativeWrapper può avere. Un XPCNativeWrapper può essere esplicito (o, all'opposto, implicito) e può essere profondo (o, al contrario, superficiale). Il tipo di imballaggio è determinato dal modo in cui è stato creato, come segue:

Creato da Esplicito/Implicito Profondo/Superficiale
Accesso di uno script protetto ad un oggetto non attendibile Implicito Profondo
Chiamata del costruttore con argomento testuale Esplicito Superficiale
Chiamata del costruttore senza argomento testuale Esplicito Profondo

Esplicito vs. Implicito

La differenza di comportamento tra un XPCNativeWrapper esplicito ed uno implicito è che l'accesso ad una proprietà tramite un XPCNativeWrapper implicito da parte di uno script non protetto NON è sicuro. L'accesso alla proprietà sarà trasmesso attraverso il wrappedJSObject del XPCNativeWrapper.

Questo significa che gli script non protetti non devono preoccuparsi di eventuali bug perché gli altri codici li tratteranno come un XPCNativeWrapper implicito. Dall'altro lato, tali script hanno bisogno di evitare l'accesso di oggetti non sicuri.

L'accesso ad una proprietà attraverso un XPCNativeWrapper esplicito è sicuro indipendentemente dalla circostanza che lo script che effettua la chiamata sia protetto o meno.

Profondo vs. Superficiale

La differenza di comportamento tra un XPCNativeWrapper profondo ed uno superficiale risiede nel fatto che quando si effettua l'accesso ad una proprietà o quando una funzione viene richiamata in un imballaggio profondo, il valore restituito sarà imballata in un suo proprio XPCNativeWrapper. Il nuovo XPCNativeWrapper sarà profondo e sarà anche esplicito se e solo se il XPCNativeWrapper al quale appartiene la proprietà alla quale si è effettuato l'accesso sia anch'esso esplicito. Al contrario, quando una si accede ad una proprietà o ad una funzione mediante un imballaggio superficiale, il valore restituito potrebbe essere un oggetto non sicuro.

Ad esempio, poniamo di avere tre istanze di XPCNativeWrapper per lo stesso oggetto window. Chiamiamole deepExplicitWindow, deepImplicitWindow e shallowWindow. Avremo quindi:

var doc1 = deepExplicitWindow.document;
// doc1 è ora un XPCNativeWrapper profondo ed esplicito
// per l'oggetto del documento.  Accedere a doc1.open() è sicuro.
var doc2 = deepImplicitWindow.document;
// Se lo script di chiamata ha impostato xpcnativewrappers=yes, doc2 è un
// XPCNativeWrapper profondo ed implicito per l'oggetto documento.
// Altrimenti doc2 è un oggetto documento non sicuro, datoché l'accesso
// alle proprietà è passato semplicemente all'oggetto non sicuro.
var doc3 = shallowWindow.document;
// doc3 è un oggetto documento non sicuro.

Creare un oggetto XPCNativeWrapper

Ci sono tre modi diversi per creare un oggetto XPCNativeWrapper; un modo per ognuno dei tre tipi.

Accesso di uno script protetto ad un oggetto non attendibile

Ogni volta che uno script protetto accede ad un oggetto non attendibile otterrà un XPCNativeWrapper implicito e profondo . L'accesso alle proprietà di questo XPCNativeWrapper da parte di uno script protetto è sicuro.

Un imballaggio creato in tal modo esisterà a lungo quanto l'oggetto imballato, e un doppio accesso all'oggetto restituirà lo stesso XPCNativeWrapper.

Che cos'è uno script protetto?

Uno script si considera protetto o non protetto a seconda del suo URI. Uno script si considera protetto solamente se il suo URI inizia con un prefisso protetto conosciuto. I prefissi protetti in Firefox 1.5 sono determinati dal Registro Chrome.

Come opzione predefinita, tutti i pacchetti di contenuti sono protetti. Questo significa che tutti gli URI che iniziano con "<tt>chrome://<package name>/content/</tt>" (per ogni pacchetto) sono protetti. I singoli pacchetti possono sovrascrivere questa regola utilizzando un contrassegno nel file chrome manifest.

Che cos'è un oggetto non attendibile?

Tutti gli oggetti possono essere sia sicuri che non sicuri. Un oggetto è attendibile se una qualsiasi delle seguenti affermazioni è soddisfatta:

  1. Il suo oggetto genitore è attendibile (la proprietà __parent__ in JavaScript).
  2. E' un oggeto che definisce il raggio d'azione di un componente JavaScript.
  3. E' l'oggetto window per una finestra attendibile.

Poiché tutti gli oggetti DOM in una finestra hanno l'oggetto window come __parent__ nella loro catena d'oggetti, sranno attendibili se e solo se anche la loro finestra risulta attendibile.

Che cos'è una finestra attendibile?

Se una finestra sia sicura o meno dipende dal suo contenitore. Una finestra è attendibile se soddisfa una delle seguenti condizioni:

  1. E' una finestra di livello principale (es. <xul:window>, <xul:dialog>, o un qualche URI passato in linea di comando con l'indicatore <tt>-chrome</tt>).
  2. L'elemento genitore è attendibile e soddisfa una di queste tre opzioni:
    1. Non viene caricato in un <xul:iframe> o <xul:browser>.
    2. E' caricato in un <xul:iframe> o <xul:browser> senza l'attributo "tipo".
    3. E' caricato in un <xul:iframe> o <xul:browser> e il valore dell'attributo "tipo" non è "content" e non inizia con "content-".

Nota che la circostanza che una finestra sia sicura non dipende dall'URI caricato nella finestra. Quindi, ad esempio, le seguenti stringhe creerebbero finestre attendibili qualora utilizzate in documenti le cui finestre siano già sicure:

  • <xul:browser>
  • <xul:browser type="chrome">
  • <xul:browser type="rabid_dog">
  • <xul:iframe type="foofy">
  • <html:iframe>
  • <html:iframe type="content">

I seguenti valori invece non creerebbero finestre attendibili:

  • <xul:browser type="content">
  • <xul:iframe type="content-primary">

N.B. qualsiasi finestra discendente di una finestra non attendibile è automaticamente un elemento non sicuro.

Cosa accade quando uno script accede ad un oggetto?

La tabella riportata sotto descrive cosa accade quando uno script accede ad un oggetto, e come viene coinvolto il "wrapper".

Script Oggetto Effetti
Protetto Attendibile Non viene creato nessun imballaggio, e dunque lo script ha un pieno accesso all'oggetto.
Protetto Non attendibile Viene creato un XPCNativeWrapper implicito e profondo.
Non protetto Attendibile Non viene creato nessun imballaggio, come nel caso protetto/attendibile.
Non protetto Non attendibile Non viene creato nessun imballaggio, come nel caso protetto/attendibile.

Chiamata del costruttore del XPCNativeWrapper con un argomento testuale

Ad esempio:

var contentWinWrapper = new XPCNativeWrapper(content,
                                             "document");

Questo crea un XPCNativeWrapper esplicito e superficiale. Questa sintassi è stata mantenta per la retrocompatibilità. Mentre l'accesso a tutte le proprietà del oggetto contentWinWrapper è ora sicuro, l'accesso al valore restituito da queste proprietà NON è sicuro (proprio come nelle versioni precedenti a Firefox 1.5), dal momento che il XPCNativeWrapper è superficiale. Quindi per confrontare il titolo del contenuto del documento con la selezione corrente del contenuto, occorre fare:

var winWrapper = new XPCNativeWrapper(content, "document",
                                      "getSelection()");
var docWrapper = new XPCNativeWrapper(winWrapper.document,
                                      "title");
return docWrapper.title == winWrapper.getSelection();

proprio come nelle versioni di Firefox precedenti alla 1.5. Nota che l'argomento "getSelection()" non è strettamente necessario in questo caso; se non si intende utilizzare tale codice con versioni precedenti a Firefox 1.5, può essere rimosso. Un singolo argomento testuale dopo l'imballaggio dell'oggetto è quanto è necessario a Firefox per creare questo tipo di XPCNativeWrapper.

Chiamata del costruttore del XPCNativeWrapper senza un argomento testuale

Ad esempio:

var contentWinWrapper = new XPCNativeWrapper(content);

Questo crea un XPCNativeWrapper esplicito e profondo. L'accesso alle proprietà di questo XPCNativeWrapper è sicuro, ed anche i valori restituiti saranno imballati in un oggetto XPCNativeWrapper profondo ed esplicito.

Impostare le proprietà "expando" in un XPCNativeWrapper

E' possibile impostare le proprietà "expando" (che sono proprietà con nomi non corrispondenti a quelli delle proprietà definite dall'IDL) in un oggetto XPCNativeWrapper. Se ciò viene fatto, il chrome sarà in grado di vedere queste proprietà "expando", ma il contenuto no. Non esiste un modo sicuro per impostare una proprietà "expando" dal chrome e fare in modo che sia poi leggibile dal contenuto.

Durata della vita di un XPCNativeWrapper

Gli oggetti XPCNativeWrapper espliciti esistono finché vi viene fatto rifierimento. Creare un nuovo XPCNativeWrapper esplicito per lo stesso oggetto potenzialmente non sicuro, genera un nuovo imballaggio; una cosa da evitare quando si impostano le proprietà "expando"

Gli oggetti XPCNativeWrapper impliciti hanno la stessa durata degli oggetti che imballano.

Accedere a proprietà non sicure

Se per qualche ragione è necessario accedere ad una proprietà non sicura, questo può essere effettuato attraverso la proprietà wrappedJSObject dell'imballaggio. Ad esempio, se docWrapper è l'imballaggio di doc, allora

docWrapper.wrappedJSObject.prop

è uguale a

doc.prop

Limitazioni a XPCNativeWrapper

Ci sono alcune proprietà comuni e stili di programmazione che non possono essere utilizzati con un XPCNativeWrapper. In particolare:

  1. L'assegnazione o la lettura di una proprietà on* su un XPCNativeWrapper di un nodo DOM o di un oggetto Window genererà un eccezione. (Occorre usare invece addEventListener, e utilizzare "event.preventDefault();" nel programma di gestione se si è già utilizzato "return false;" prima.)
  2. L'accesso ai frame tramite il nome della finestra (es. window.frameName) non funziona con un XPCNativeWrapper
  3. document.all non funziona in un XPCNativeWrapper per un documento.
  4. L'accesso ad oggetti con un id (nome) tramite l'id non funziona con un XPCNativeWrapper per un documento HTML. Per esempio, se si ha <form name="foo"> e docWrapper è l'imballaggio del documento HTML doc allora doc.foo è un HTMLFormElement mentre docWrapper.foo è undefined. Deve essere utilizzato docWrapper.forms.namedItem("foo").
  5. L'accesso ai nodi attraverso l'id non funziona con un XPCNativeWrapper per un documento HTML. Dovrebbe essere utilizzato getElementById.
  6. L'accesso agli input attraverso il nome non funziona con un XPCNativeWrapper per un modulo (form) HTML. Bisogna usare form.elements.namedItem("inputname").
  7. L'accesso ad elementi attraverso il nome non funziona con un XPCNativeWrapper per un HTMLCollection. Occorre usare il metodo namedItem(). Nota che namedItem restituisce solo il primo elemento di input con il nome, anche se vi sono elementi multipli (es. bottoni radio) che abbiano lo stesso nome.
  8. I metodi di chiamata implementati dai plug-in NPAPI attraverso il XPCNativeWrapper dei nodi corrispondenti non funzionano.
  9. Non è possibile ottenere o impostare proprietà implementate da plug-in NPAPI attraverso il XPCNativeWrapper dei nodi corrispondenti.
  10. I metodi di chiamata implementati attraverso XBL binding associati ad un nodo attraverso il XPCNativeWrapper di quel nodo, non funzionano.
  11. Non è possibile ottenere o impostare proprietà implementate attraverso XBL binding associati ad un nodo attraverso il XPCNativeWrapper di quel nodo.
  12. L'elenco delle proprietà di un XPCNativeWrapper attraverso "for (var p in wrapper)" non cpntiene le proprietà definte dall'IDL.
  13. Object.prototype non appartiene alla catena di prototipi di un XPCNativeWrapper. Come risultato, molte proprietà Object.prototype non sono definite in un XPCNativeWrapper (per essere precisi queste sono __proto__, __parent__, __count__, toSource, toLocaleString, valueOf, watch, unwatch, hasOwnProperty, isPrototypeOf, propertyIsEnumerable, __defineGetter__, __defineSetter__, __lookupGetter__, e __lookupSetter__).
  14. Non esiste più il supporto per il metodo importXPCNative che le vecchie implementazioni di XPCNativeWrapper erano solite avere.
  15. L'accesso a classi standard (come Function) attraverso un XPCNativeWrapper non avrà effetto. Per creare funzioni e oggetti con una particolare finestra genitore, occorre utilizzare la funzione eval di quella finestra.

Evitare insidie comuni in Greasemonkey(EN) contiene una elaborata spiegazione di alcune di queste limitazioni (sebbene nel contesto degli script di Greasemonkey).

Tag del documento e collaboratori

 Hanno collaborato alla realizzazione di questa pagina: Indigo
 Ultima modifica di: Indigo,