Geckozone est un Club Unesco

La politique de sécurité paramétrable

Profil(s) : Confirmé Développeur
Date : 19 août 2004
Auteur : siruphi

La politique de sécurité de Mozilla permet de paramétrer des règles de sécurité, globales à la navigation sur Internet, et personnalisées à chaque site internet rencontré. Ce document est destiné à des programmeurs familiers du JavaScript. Il a été traduit du wiki de Mozilla.

Les idées de cette configuration avancée sont issues de plusieurs documents : les écrits des chercheurs Vinod Anupam et Alain Mayer, des laboratoires Bell, qui ont contribué à l’écriture du code de Mozilla, et le rapport de bug 858 qui liste les fonctionnalités souhaitées dans ce domaine de la sécurité. Le nom de code de cette politique est CAPS (capabilities).

Le principe est de contrôler le comportement de Mozilla à travers son fichier de configuration. Le comportement globale de Mozilla est indiqué dans la règle default qui est appliquée uniformément à tous les sites. Et si on a besoin d’indiquer des règles particulières à un site ou un groupe de sites, on utilise des règles de groupe. Tout cela est détaillé ci-après.

Paramétrer des règles par défaut

Si par exemple vous êtes gêné par les popups publicitaires, vous pouvez empêcher toutes les pages d’ouvrir une nouvelle fenêtre en ajoutant la ligne suivante à votre fichier de configuration de Mozilla (user.js ou prefs.js) :

user_pref("capability.policy.default.Window.open", "noAccess");

Cette règle s’appliquera à tous les sites

Paramétrer Window.open avec l’option noAccess signifie que les pages web ne pourront pas accéder à la propriété open des objets de type Window. De cette façon, si une page essaie d’ouvrir une nouvelle fenêtre en utilisant window.open() (ou open()), la tentative échouera. Le gestionnaire de sécurité émettra alors une interdiction JavaScript, empêchant la fonction d’être exécutée. Si la page Web ne remarque pas l’interdiction, le script s’arrête, et un message d’erreur s’inscrit dans la console Javascript (Outils -> Console JavaScript).

Paramétrer des règles de groupe

La règle default vue précédemment s’applique de la même façon à tous les sites. Les règles spécifiques (visant des sites ou des groupes de sites particuliers) complètent ou remplacent les réglages par défaut de la règle default. Par exemple, pour empêcher seulement www.demon.org et www.genant.fr d’ouvrir des boîtes de dialogue, le code suivant convient :

user_pref("capability.policy.policynames", "stricte");
user_pref("capability.policy.stricte.sites", "http://www.demon.org http://www.genant.fr");
user_pref("capability.policy.stricte.Window.alert", "noAccess");
user_pref("capability.policy.stricte.Window.confirm", "noAccess");
user_pref("capability.policy.stricte.Window.prompt", "noAccess");

La première ligne définit le nom de la règle ou des règles que vous voulez créer, ici stricte ; plusieurs règles peuvent-être énumérées sur une même ligne selon cette syntaxe :

user_pref("capability.policy.policynames", "stricte, permissive, ");

Le paramètre capability.policy.stricte.sites - à la deuxième ligne - définit les sites pour lesquels la règle stricte est appliquée. Les sites concernés sont séparés par un espace, et seuls le protocole et la racine du site sont indiqués.

Les dernières lignes - ici trois - définissent les options de la règle stricte, dans l’exemple nous avons interdit l’accès à window.alert(), window.confirm(), et window.prompt() pour empêcher l’ouverture de boîtes de dialogue.

Remarquez que puisque nous n’avons pas défini si les sites soumis à la règle stricte pouvaient ouvrir de nouvelles fenêtres avec window.open(), la règle défaut - vue en tout premier- s’applique encore pour eux.

Supposons qu’en bloquant l’accès à window.open(), nous empêchions un script de fonctionner sur www.siteutile.net. Nous pouvons permettre à ce site de contourner le bloquage de la fonction window.open en créant une nouvelle règle qui permettra au site d’utiliser la fonction. On remplace le noAccess par sameOrigin et cela donne :

user_pref("capability.policy.policynames", "confiance");
user_pref("capability.policy.confiance.sites", "http://www.siteutile.net");
user_pref("capability.policy.confiance.Window.open", "sameOrigin");

Le nom de la règle peut être celui que vous voulez ; nous avons utilisé stricte et confiance dans cet exemple, mais vous pourriez l’appeler liste_noire ou ma_regle ou encore tout autrement.

Niveaux de Sécurité

Il y a trois niveaux de sécurités spéciaux :

  • noAccess : les sites ne pourront jamais accéder à la propriété ni appeler la fonction.
  • sameOrigin (valeur par défaut) : un site peut accéder à la propriété, mais seulement pour des pages de ce même site. Voir ce document pour comprendre comment Mozilla détermine si deux pages ont la même origine.
  • allAccess : un site Web peut accéder à la propriété dans le même site et sur n’importe quel autre site.

Si le niveau de sécurité n’est pas l’un des trois ci-dessus, il est interprété comme un nom de privilège, et un script ne peut y accéder que s’il est signé et que l’utilisateur lui accorde le privilège via une boite de dialogue.

Gérer le droit en lecture et en écriture

Vous pouvez spécifier une règle qui autorise un site à lire une propriété et/ou à changer sa valeur, en ajoutant .get (lecture) ou .set (écriture) après le nom de la propriété. Voir à la fin quelques exemples.

Définir une classe.propriété.get et une classe.propriété.set au même niveau, avec les mêmes droits, revient à définir globalement une classe.propriété. Après le nom de fonctions (comme open ou write) get et set ne s’appliquent pas, ils ne s’appliquent qu’aux propriétés qui ne sont pas des fonctions (telles que bgColor ou location).

Déterminer des noms d’objets

Déterminer le bon nom d’un objet à utiliser est parfois délicat. Imaginons que vous vouliez empêcher une page web de vous proposer un formulaire, mais que vous ne connaissez pas le nom de la classe d’un élément du formulaire. Le plus simple c’est de le découvrir par un script qui convertit l’objet en chaîne de caractère. Si vous allez sur une page avec un formulaire et que vous saisissez javascript:alert(document.forms[0]) dans la barre d’adresse, vous verrez que document.forms[0] est un [xpconnect wrapped HTMLFormElement]. HTMLFormElement est le nom de la classe, ainsi vous pouvez paramétrer HTMLFormElement.submit avec noAccess pour empêcher des pages Web de soumettre des formulaires par form.submit.

Des éléments comme HTMLAnchorElement ont des fonctions toString qui empêchent de trouver facilement leur nom de classe. Si vous saisissez javascript:alert(document.links[0]) dans la barre d’adresse, vous verrez l’URL du premier lien au lieu de son nom de classe. La manière de venir à bout de ce problème est d’employer la fonction toString sur l’objet document.links[0 ], comme ceci :

javascript:alert(window.toString.apply(document.links[0]))

Attention : certaines propriétés ont des voies d’accès multiples

Lorsqu’on bloque l’accès à certaines propriétés, il est important de noter qu’il y a plusieurs façons d’y accéder. Prenons l’exemple de l’élément <a href="..."> dont on désire qu’il ne soit pas accessible par les scripts de www.demon.org. Les préférences suivantes ne suffiront pas :

user_pref("capability.policy.policynames", "nohrefs");
user_pref("capability.policy.nohrefs.sites", "http://www.demon.org");
user_pref("capability.policy.nohrefs.HTMLAnchorElement.href", "noAccess");

Alors que ces paramètres empêcheront aux scripts de www.demon.org d’accéder à document.links[1].href, ces mêmes scripts pourront encore y accéder en utilisant une syntaxe DOM 2, comme document.links[1].attributes.getNamedItem("href") ou document.links[1].getAttribute("href"). Voici les règles pour bloquer totalement l’accès à l’attribut href :

user_pref("capability.policy.policynames", "nohrefs");
user_pref("capability.policy.nohrefs.sites", "http://www.demon.org");
user_pref("capability.policy.nohrefs.HTMLAnchorElement.href", "noAccess");
user_pref("capability.policy.nohrefs.HTMLAnchorElement.attributes", "noAccess");
user_pref("capability.policy.nohrefs.HTMLAnchorElement.getAttribute", "noAccess");
user_pref("capability.policy.nohrefs.HTMLAnchorElement.getAttributeNS", "noAccess");

Il faut retenir que pour empêcher l’accès à un attribut, on doit bloquer : les propriétés de l’attribut, le getAttribute et les méthodes getAttributeNS.

La syntaxe complète des préférences

Voici la syntaxe pour configurer les autorisations JavaScript :

Une règle est constituée de trois lignes minimum, une pour le nom de la règle, une pour les sites qui appliqueront la règle, et une ou plusieurs autres pour la description de la règle.

user_pref("capability.policy.policynames", "<nom de la règle ou des règles>");
user_pref("capability.policy.<nom de la règle>.site", "<liste des URLs des sites concernés par la règle>");
user_pref("capability.policy.<règle>.<classe>.<propriété>","allAccess ou noAccess ou sameOrigin ou <capability name>");

Explication détaillée :

  • La première ligne (policynames) indique le nom de la règle ou des règles que vous voulez définir. Il ne doit y avoir qu’une seule ligne policynames mais le nombre de règles dans cette ligne est illimité. Le nom d’une règle doit être une suite de lettres et de chiffres commençant par une lettre. Voici un exemple de syntaxe avec trois règles :
user_pref("capability.policy.policynames", "regle1, regle2, regle3");
  • La ligne sites sert à indiquer les sites concernés par la règle. Il y a donc autant de lignes sites que de règles. Chaque URL de cette liste peut être notée sous la forme de “protocole:” pour appliquer la règle à toute URL d’un protocole donné (tel que le HTTP), ou bien “protocole://hôte” qui appliquera la règle à un domaine particulier - par exemple, http://www.sitenul.fai.com. Voici un exemple de syntaxe avec trois règles :
    user_pref("capability.policy.regle1.sites","http://siteutile.net");
    user_pref("capability.policy.regle2.sites","ftp://telechargement.securise.fr");
    user_pref("capability.policy.regle3.sites","http://demon.org http://sitepassur.com");
  • Les dernières lignes, de la forme user_pref("capability.policy.<règle>.<classe>.<propriété>...), définissent la règle, où doit être la même que celle définie dans la ligne sites ; et les préférences (allAccess, etc.), les mêmes que celles décrites plus haut dans ce document.

Désactiver le Javascript pour un site

La propriété javascript.enabled peut servir à désactiver le JavaScript, de façon globale en utilisant les règles par défaut ou pour certains sites en utilisant les règles de sites. Pour cette règle, les seules options possibles sont noAccess ou allAccess. L’exemple suivant interdit le JavaScript pour site1.fr et site2.com :

user_pref("capability.policy.policynames", "nojs");
user_pref("capability.policy.nojs.sites", "http://site1.fr http://site2.com");
user_pref("capability.policy.nojs.javascript.enabled", "noAccess");

Cet exemple empêche l’exécution du JavaScript pour tous les sites sauf bonsite.fr :

user_pref("capability.policy.policynames", "jsok");
user_pref("capability.policy.default.javascript.enabled", "noAccess");
user_pref("capability.policy.jsok.sites", "http://bonsite.fr");
user_pref("capability.policy.jsok.javascript.enabled", "allAccess");

Remarquez que les options allAccess et noAccess fonctionnent avec javascript.enabled policy prefs. Il ne faut pas utiliser sameOrigin dans ce cas. Attention aussi car cette option : user_pref("javascript.enabled", false); interdit totalement l’exécution du JavaScript.

Exemples supplémentaires

Empêcher le Javascript de :

  • Redimensionner la fenêtre du navigateur :
    user_pref("capability.policy.default.Window.innerWidth.set", "noAccess");
    user_pref("capability.policy.default.Window.innerHeight.set", "noAccess");
    user_pref("capability.policy.default.Window.outerWidth.set", "noAccess");
    user_pref("capability.policy.default.Window.outerHeight.set", "noAccess");
    user_pref("capability.policy.default.Window.sizeToContent", "noAccess");
    user_pref("capability.policy.default.Window.resizeTo", "noAccess");
    user_pref("capability.policy.default.Window.resizeBy", "noAccess");
  • Déplacer la fenêtre du navigateur :
    user_pref("capability.policy.default.Window.screenX.set", "noAccess");
    user_pref("capability.policy.default.Window.screenY.set", "noAccess");
    user_pref("capability.policy.default.Window.moveTo", "noAccess");
    user_pref("capability.policy.default.Window.moveBy", "noAccess");
  • Trouver les réglages d’écran (résolution et nombre de couleurs) :
    (Remarque : ces lignes ne bloquent pas tous les accès possibles pour obtenir ces informations, mais simplement les plus courants. Par exemple, elles n’empêchent pas de trouver la taille de la fenêtre de navigation.)
    user_pref("capability.policy.default.Screen.top", "noAccess");
    user_pref("capability.policy.default.Screen.left", "noAccess");
    user_pref("capability.policy.default.Screen.width", "noAccess");
    user_pref("capability.policy.default.Screen.height", "noAccess");
    user_pref("capability.policy.default.Screen.pixelDepth", "noAccess");
    user_pref("capability.policy.default.Screen.colorDepth", "noAccess");
    user_pref("capability.policy.default.Screen.availWidth", "noAccess");
    user_pref("capability.policy.default.Screen.availHeight", "noAccess");
    user_pref("capability.policy.default.Screen.availLeft", "noAccess");
    user_pref("capability.policy.default.Screen.availTop", "noAccess");
  • Changer le texte de la barre d’état :
    Certaines pages créent des liens cachés (blind links) qui changent le contenu de la barre d’état quand la souris passe au dessus d’eux pour ne pas qu’on voie le lien de l’adresse vers laquelle pointe le lien. Cette ligne annule quasiment tous les liens cachés. user_pref("capability.policy.default.Window.status", "noAccess");

L’interface d’utilisation

L’extension Policy Manager aide à configurer facilement ces propriétés, sans nécessiter d’éditer manuellement les fichiers user.js ou prefs.js (limitant ainsi les erreurs de saisie). Développée par Piro, elle a été traduite en français par Olab.

Articles dans la même rubrique