Cette page vous explique comment faire des scripts sécurisés dans vos extensions, quand il s'agit de manipuler les données d'une page web distante.
L'une des possibilités de javascript est de pouvoir redéfinir à la volée les méthodes et propriétés d'un objet. Il est ainsi tout a fait possible donc de redéfinir des méthodes des objets DOM dans une page web. Un exemple :
document.getElementById = function(id){ alert('hello world !'); }
Chaque fois donc qu'on appellera en javascript document.getElementById(), on aura un message "hello world", plutôt que l'execution de la vraie méthode getElementById ( qui récupère normalement un élément qui a l'id indiqué).
Quand c'est un script de la page web qui appelle cette nouvelle méthode, ce n'est pas grave. Le code de la méthode est toujours executée hors privilège chrome puisque le script est distant. Et puis si la page web modifie les méthodes existantes pour ses propres besoins, c'est son problème.
Quand c'est à partir d'un script d'une extension (en faisant contentWindow.document.getElementById() par exemple), c'est beaucoup plus dangereux. En effet, votre extension ayant tous les privilèges chrome, cela voudrait dire que lorsqu'elle appelle la méthode getElementById de l'objet document correspondant à la page web distante, le code de cette méthode est executée avec tous les privilèges chrome. Il s'agit alors d'un défaut de sécurité. Imaginez en effet que ce code fasse quelque chose de beaucoup plus malhonnête qu'un simple hello world ;-) (lire un fichier sur le disque local par exemple).
Heureusement, il y a un système de sécurité qui permet d'être sûr qu'on appelle la méthode originale d'un objet définit par Firefox : XPCNativeWrapper.
Il y a donc deux méthodes pour appeller une propriété d'un objet : l'accés direct classique (document.getElementById()) ), et l'accés via XPCNativeWrapper.
L'accés via XPCNativeWrapper est toujours sûr. Vous n'avez pas à vous inquieter de savoir si il y a du code malicieux ou non. Vous êtes certains que ce que vous appelez est bien la propriété originale de l'objet quand celui ci est défini par défaut par Firefox.
L'accés direct par contre, n'est pas toujours sûr. Cela dépend de la version de Firefox.
Pour la version 1.0.2 et inférieur : c'est totalement non sécurisé. Vous ne devez absolument pas utiliser l'accés direct pour les objets d'une page distante, car vous n'avez aucun moyen de savoir si l'objet est bien du type attendu, ou si c'est un objet redéfini. Il est donc impératif de passer explicitement par XPCNativeWrapper.
Pour les version 1.0.3 et suivantes jusqu'à Firefox 1.5 non inclus : vous pouvez vérifier que l'accés est sûr en faisant appel à l'operateur instanceof sur l'objet. Cela vous renvoi alors le type de l'objet que vous pouvez alors tester pour savoir si c'est bien le type attendu. Si ce n'est pas le cas, vous ne devez pas utiliser l'objet (et provoquer une erreur). Si par contre le type est bien le bon, vous pouvez utiliser l'objet sans crainte. Il est donc impératif de faire ce test avant l'utilisation d'un objet d'une page web distante.
Pour les versions 1.5 et suivante : l'accés direct est sûr si vous activez l'utilisation implicite de XPCNativeWrapper dans le manifeste de l'extension, avec xpcnativewrappers=yes.
Pour être sûr d'utiliser la propriété originale d'un objet, il faut utiliser l'objet XPCNativeWrapper, en lui indiquant l'objet à appeler, et la liste des propriétés que l'on veut utiliser
var winWrapper = new XPCNativeWrapper(contentWindow, 'document', 'getSelection()');
Ici on crée un objet winWrapper, qui va vérifier l'objet contentWindow (qui est un objet de type window), et "activer" la version originale de la propriété 'document' et de la méthode "getSelection()". L'objet renvoyé et donc stocké ici dans winWrapper, est l'objet contentWindow "sécurisé".
Aussi, quand vous ferez appel à winWrapper.document ou winWrapper.getSelection(), ce sera bien la propriété et la méthode qui sont définies originellement par Mozilla Firefox et non une redéfinition éventuelle faite dans la page web.
Attention, ici la propriété document de contentWindow sera bien une référence vers un objet document, mais peut être a-t-il été lui même modifié. Il faut donc sécuriser les propriétés et méthodes auxquels on veut faire appel. On fera donc, pour acceder à la propriété title :
var docWrapper = new XPCNativeWrapper(winWrapper.document, 'title');
alert("ceci est le vrai titre du document : " + docWrapper.title);
L'utilisation explicite de XPCNativeWrapper est possible dans toutes les versions de Firefox. Cependant, dans DeerPark, Firefox 1.5 et suivant, cette utilisation est implicite si vous l'activez dans le manifest de l'extension. Ainsi donc, si il y a xpcnativewrappers=yes dans le manifeste, vous pouvez alors utiliser tranquillement dans vos scripts l'accés direct
alert("ceci est le vrai titre du document : " + contentWindow.document.title);
Si vous faites une extension pour Firefox < 1.5, vous devez utiliser explicitement XPCNativeWrapper.
Si vous faites une extension pour Firefox >= 1.5, vous devez mettre xpcnativewrappers=yes dans le manifeste de votre extension et vous pouvez ainsi appeler les objets comme à l'habitude. Mais activez xpcnativewrappers seulement si vos scripts accédent au contenu de pages web distantes (ça rend en effet les scripts un peu plus lent).
Voir les explications en français : Accès sécurisé au contenu DOM depuis le chrome
Copyright © 2003-2013 association xulfr, 2013-2016 Laurent Jouanneau - Informations légales.
Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™
sont des marques de la fondation Mozilla.