Introduction
Les applications et les extensions scriptant des interfaces DOM sur du contenu non fiable (une page Web) doivent être prudentes et s'assurer que les informations utilisées proviennent bien de l'API DOM et non de propriétés JavaScript ou de fonctions getter et setter (accesseur/mutateur) redéfinies par une page malveillante. Firefox 1.0.3 et Mozilla 1.7.7 rendent la tâche plus difficile aux pages Web essayant de tromper les applications XUL en s'assurant que lorsque du JavaScript chrome accède à une propriété ou méthode DOM sur un objet, il obtiendra bien la propriété ou méthode DOM plutôt que la redéfinition faite par la page Web. Firefox 1.5 propose une solution plus générale qui est activée par défaut ; les extensions doivent explicitement le demander pour pouvoir effectuer des accès DOM non sûrs.
Il n'y a que deux manières « correctes » pour le code chrome d'accéder au DOM du contenu : l'accès direct et l'utilisation explicite de XPCNativeWrapper. En particulier, l'astuce __proto__
couramment utilisée n'est sûre dans aucune version (voir « Exemples à ne PAS suivre » ci-dessous).
La table suivante rassemble les propriétés de sécurité des deux méthodes « correctes » :
Accès direct | XPCNativeWrapper explicite | |
---|---|---|
Firefox 1.0.2 et antérieur | non sécurisé | sécurisé |
Firefox 1.0.3 et postérieur (1.0.x) | sécurisé lorsqu'il est certain que la propriété existe | sécurisé |
Firefox 1.5 | sécurisé avec xpcnativewrappers=yes (qui est le réglage par défaut)
| sécurisé |
Accès direct
Les scripts conçus pour s'exécuter uniquement dans Firefox 1.0.3 et les versions 1.0.x plus récentes ou qui utilisent xpcnativewrappers=yes
dans Firefox 1.5 ou plus récent peuvent simplement appeler :
return contentWindow.document.title == contentWindow.getSelection();
L'accès direct est sécurisé dans Firefox 1.0.3 (et les versions 1.0.x suivantes) dans la mesure où l'objet a la garantie de bénéficier de la propriété ou de la méthode accédée par sa déclaration IDL. Par exemple, foo.nodeType
est sûr si vous avez l'assurance que foo
est de type Node
, et foo.getSelection()
est sûr si foo
ne peut être qu'un objet window
. Il peut être complexe d'y arriver -- par exemple, nsIDOMNSHTMLDocument
a une méthode open()
, mais nsIDOMXULDocument
n'en a pas, par conséquent utiliser document.open()
n'est PAS sûr dans Firefox 1.0.3, étant donné que document
peut être un document XUL. Dans de tels cas, vous pouvez utiliser l'opérateur instanceof
pour déterminer si vous avez un objet implémentant une interface IDL donnée (nsIDOMNSHTMLDocument
dans ce cas précis).
Dans Firefox 1.5, l'accès direct est toujours sûr, sauf si votre extension utilise le paramètre xpcnativewrappers=no
dans son fichier manifest. Si ce paramètre n'est pas défini, l'utilisation de XPCNativeWrapper est implicite.
Utilisation explicite de XPCNativeWrapper
var winWrapper = new XPCNativeWrapper(contentWindow, 'document', 'getSelection()'); var docWrapper = new XPCNativeWrapper(winWrapper.document, 'title'); return docWrapper.title == winWrapper.getSelection();
Notez que cet exemple utilise deux wrappers pour obtenir window.document.title
, un wrapper pour obtenir la propriété document
de l'objet window
, et un wrapper pour obtenir la propriété title
du document.
L'utilisation de XPCNativeWrapper est sûre dans toutes les versions de Firefox, mais rend le code plus difficile à lire et vous devez faire attention à envelopper tous les objets DOM.
Pour plus d'informations sur cette syntaxe, consultez l'entrée sur XPCNativeWrapper
de la MozillaZine KnowledgeBase.
À propos de XPCNativeWrapper
XPCNativeWrapper
est une manière d'envelopper un objet de manière à ce que son accès par du code privilégié soit sûr.
Il y a deux façons d'utiliser XPCNativeWrapper
. L'ancienne est de l'appeler explicitement. La nouvelle manière, xpcnativewrappers=yes
, est disponible à partir de Firefox 1.5 et ses pré-versions Deer Park alpha et beta.
Exemples à ne PAS suivre
MAUVAIS dans Firefox 1.0.2 et antérieur, car un script pourrait redéfinir l'accesseur nodeType
:
return targetNode.nodeType == 1;
MAUVAIS dans Firefox 1.0.2 et antérieur, car un script pourrait redéfinir getSelection
:
return contentWindow.getSelection();
MAUVAIS dans toutes les versions. Certains développeurs mal conseillés ont utilisé cette astuce dans le passé. Des scripts peuvent redéfinir getSelection
dans d'anciennes versions et cela ne fonctionne plus du tout dans Firefox 1.0.3 et Mozilla 1.7.7 :
return contentWindow.__proto__.getSelection.call(contentWindow);
MAUVAIS dans Firefox 1.0.2 et antérieur, car un script pourrait redéfinir le second accesseur même si le premier est sûr :
var winWrapper = new XPCNativeWrapper(contentWindow, 'document'); // accéder à contentWindow.document est à présent sûr, mais récupérer .title du // document obtenu ne l'est toujours pas. return winWrapper.document.title;
MAUVAIS dans les versions antérieurs à Firefox 1.5, car les scripts peuvent définir document.open
pour les documents non-HTML, qui n'ont pas la fonction DOM document.open
:
return contentWindow.document.open();