Les privilèges dans firefox

Les Privilèges dans Firefox

Qu'est-ce que c'est ?

Les privilèges dans Firefox est un sujet peu connu des développeurs et mal documenté sur Internet. Je tenterai de faire du mieux pour donner des informations à jour et de donner des explications claires et de nombreux exemples. Pourquoi est-ce peu connu des développeurs ? Car les privilèges sont exclusifs à Firefox et une demande sera envoyée à l'utilisateur, qui risque de la refuser par panique.

Que verrons-nous dans ce tutoriel ?

Nous verrons principalement les deux principales méthodes, soit netscape.security et navigator.preference .

Netscape.security.privilegeManager

Wow ! Cela sonne long ^^ En effet, l'objet netscape (de window ) ne contient qu'un seul objet security qui ne contient qu'un seul objet privilegeManager . Du moins, à ma connaissance.

Cet objet sort directement du Java et a été implanté par... Netscape ^^

Méthodes

privilegeManager contient maintenant 3 seuls méthodes. Dans le passé, il en contenait beaucoup plus mais selon les tests que j'ai fait avec Firefox, beaucoup ont été supprimé.

enablePrivilege() Active un privilège passé en paramètre
disablePrivilege() Désactive un privilège passé en paramètre
revertPrivilege() Active un privilège passé en paramètre s'il est désactivé ou le désactive dans le cas contraire.

Un privilège, un privilège.... mais au fait ? Qu'est-ce qu'un privilège ? C'est une permission accordé par l'utilisateur au développeur à utiliser des données sensibles ou à faire des actions sensibles. Calmez-vous ! Vous ne pourrez pas faire exploser l'ordinateur du voisin !

Les privilèges à passer en paramètre sont les même pour les 3 méthodes. Ceux-ci peuvent être les suivants :

  • UniversalBrowser Write
  • UniversalBrowser Read
  • UniversalXPConnect
  • UniversalPreferencesRead
  • UniversalPreferencesWrite
  • CapabilityPreferencesAccess
  • UniversalFileRead

Nous les verrons chacune en détail. Mais d'abord, voici comment demander un privilège :

if(window.netscape){
try{
netscape.security.PrivilegeManager.enablePrivilege('UniversalPreferencesRead');
}
catch(e){
alert('Non-autorisé');
}
}
else{
alert('Vous ne supportez pas les privilèges');
}

On commence par tester la présence de l'objet window.netscape. Si l'objet est présent, on utilise try... catch (gestionnaire d'exception) pour l'appel. En effet, si l'utilisateur refuse la demande, le navigateur provoquera une exception qui nous enverra donc dans le bloc catch. Si l'objet n'est pas présent, on envoie un message d'erreur. Bien sûr, il est possible de personnaliser le tout.

UniversalBrowserWrite

UniversalBrowserWrite permet d'avoir un accès élargi aux propriétés de la fenêtre ou plus officiellement de pouvoir "modifier n'importe quelle fenêtre ouverte". Qu'est-ce que cela veut dire ? Un petit exemple pour commencer :

<html>
<head>
<title>Exemple : Avoir le plein écran</title>
<script type="application/javascript">
if(window.netscape){
try{
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserWrite');
window.fullScreen=true;
}
catch(e){
alert('Non-autorisé');
}
}
else{
alert('Vous ne supportez pas les privilèges');
}
</script>
</html>

Dans cette exemple, nous avons d'abord fait une demande de privilège via netscape.security.PrivilegeManager.enablePrivilege pour pouvoir modifier la propriété fullScreen de window qui spécifie si le site est en plein écran. En résumé, on a mis la page en plein écran.

En gros, UniversalBrowserWrite permet de modifier des paramètres de la page que seul l'utilisateur devrait pouvoir modifier.

Plusieurs possibilités sont permises par UniversalBrowserWrite dont pouvoir fermer la fenêtre sans condition :

<html>
<head>
<title>Exemple :         Fermer sans condition        </title>
<script type="application/javascript">
if(window.netscape){
try{
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserWrite');
window.        close();
}
catch(e){
alert('Non-autorisé');
}
}
else{
alert('Vous ne supportez pas les privilèges');
}
</script>
</html>

On peux aussi par exemple bouger la fenêtre en dehors de l'écran, rapetissez la page en bas de 100x100 pixels...

UniversalBrowserRead

UniversalBrowserRead n'a pas vraiment d'utilité. Il sert à lire des informations de la page. Seulement, toutes les informations qu'il peux soutirer peuvent l'être sans demander une autorisation (si vous avez une preuve du contraire, merci de me le dire)

UniversalXPConnect

UniversalXPConnect permet de pouvoir autorisé les échanges entre les objet XPCOM et javascript. Pour un rappel très rapide, les objets XPCOM sont les extensions Firefox. Comme je ne m'y connaît pas dans cette technologie mais j'ai quand même réussi à vous créer un exemple à l'aide d'un code que j'ai trouvé par hasard qui l'utilisait. Ce code permet de copier un texte dans le Presse-papier :

<html>
<head>
<title>Exemple : Copier un texte à l'aide de UniversalXPConnect</title>
<script type="application/javascript">

function CopyToClipboard(element){

if (window.clipboardData){
window.clipboardData.setData('text', element.value);
return false
} 
else if(window.netscape){
try{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

var clipboardhelper = Components.classes["@mozilla.org/widget/clipboardhelper;1" * .getService(Components.interfaces.nsIClipboardHelper);
clipboardhelper.copyString(element.value)
}

catch(e){alert('Vous avez refusé la demande de privilège');}}
else{
alert('Vous ne supportez pas les privilèges');
}
}
</script>

<center>
 Copier 

<textarea id ='txt'>Texte à copier</textarea>
</center>

</html>

Expliquer ce code est au-dessus de mes connaissances. Seulement, je peux tenter de vous expliquer. Si window.clipboardData est existant (sur Internet Explorer), alors on copie le texte de la boîte de saisie. Sinon, on appelle la fonction netscape.security.PrivilegeManager.enablePrivilege avec comme paramètre UniversalXPConnect. Puis, si la demande est accepté, on donne à la variable clipboardhelper la valeur de Components.classes["@mozilla.org/widget/clipboardhelper;1" * . getService(Components.interfaces.nsIClipboardHelper) . Cette ligne retourne l'interface du copier/coller. Puis, on appelle la fonction copyString() de l'objet dont je viens de vous parler avec comme param ètre la valeur à copier, c'est à dire le texte de la boîte de saisie.

UniversalPreferencesRead

C'est surtout dans UniversalBrowserRead et UniversalPreferencesRead/Write que l'on trouve le vrai intérêt. UniversalPreferencesRead permet de lire les préférences du navigateur via navigator.preference() . Cette fonction possède deux paramètres : Le premier est la préférence et le deuxième, optionnel, est sa nouvelle valeur. Si un deuxième paramètre n'est pas spécifié, la valeur de la préférence sera retourné. UniversalPreferencesRead/Write doit être déclaré avant. Compatible Firefox Seulement. Exemple :

<html>
<head>
<title>Exemple : Connaître la page d'accueil</title>
<script type="application/javascript">
if(window.netscape){
try{
netscape.security.PrivilegeManager.enablePrivilege('Universal PreferencesRead  ');
alert("Votre page d'accueil est :         "        +navigator.preference('browser.startup.homepage')        )

}
catch(e){
alert('Non-autorisé');
}
}
else{
alert('Vous ne supportez pas les privilèges');
}
</script>
</html>

On Commence par demander la permission UniversalPreferencesRead pour lire les préférences. Ensuite, on appelle la fonction navigator.preference avec comme propriété browser.startup.homepage (nom de la préférence de la page d'accueil).

Les noms des préférences sont disponibles sur la page about:config de Firefox. Voici certains noms de propriétés plus importantes :

  • autoupdate.enabled : si SmartUpDate est activé. Attend une valeur booléenne pour le modifier.
  • browser.background_color : La couleur de fond par défaut des pages web. Attend la couleur pour le modifier.
  • browser.cache.disk_cache_size : La taille du cache sur le disque dure. Attend une nouvelle valeur pour le modifier.
  • browser.enable_style_sheets : si les feuilles de style (CSS) sont activées. Attend une valeur booléenne pour le modifier.
  • browser.foreground_color : la couleur par défaut du texte. Attend la couleur pour le modifier.
  • browser.startup.page : la page de démarrage par défaut. Attend comme nouvelle valeur une adresse URL.
  • browser.window_rect : la taille et la position par défaut du navigateur.
  • general.always_load_images : si les images sont automatiquements chargées. Attend une valeur booléenne pour le modifier.
  • javascript.enabled : si Javascript est activé. Attend une valeur booléenne pour le modifier.
  • network.cookie.cookieBehavior : Comment le navigateur gère les cookies. Mettez 0 pour accepter tous les cookies, 1 pour accepter uniquement les cookies envoyé au serveur [? * et 2 pour désactiver les cookies.
  • network.cookie.warnAboutCookies : si le navigateur doit avertir l'utilisateur avant d'accepter un cookie. Attend une valeur booléenne pour le modifier.
  • security.enable_java : si le navigateur doit activer Java. Attend une valeur booléenne pour le modifier.

Mais il est aussi possible de lire des préférences pour tester la présence de plugins. Exemple :

<html>
<head>
<title>Exemple : Connaître la présence de Firebug</title>
<script type="application/javascript">
if(window.netscape){
try{
netscape.security.PrivilegeManager.enablePrivilege('UniversalPreferencesRead');
if(navigator.preference('extensions.firebug.textSize')!=undefined){
document.write('Firebug présent');
}
else{
document.write('Firebug non-présent');
}

}
catch(e){
alert('Non-autorisé');
}
}
else{
alert('Vous ne supportez pas les privilèges');
}
</script>
</html>

Cette fonction découvre si Firebug est présent en vérifiant si la préférence extensions.firebug .textSize ne vaut pas undefined .

UniversalPreferencesWrite

Même chose que UniversalPreferencesWrite mais en permettant de modifier ces informations. Cet exemple va changer votre page d'accueil :

<html>
<head>
<title>Exemple : Changer la page d'accueil</title>
<script type="application/javascript">
if(window.netscape){
try{
netscape.security.PrivilegeManager.enablePrivilege('Universal PreferencesWrite');
navigator.preference('browser.startup.homepage','http://www.javascriptfr.com')

}
catch(e){
alert('Non-autorisé');
}
}
else{
alert('Vous ne supportez pas les privilèges');
}
</script>
</html>

CapabilityPreferencesAccess

CapabilityPreferencesAccess permet de lire et régler les paramètres qui définissent les politiques de sécurité, y compris les privilèges qui ont été acceptées et refusées à des scripts ou plus officiellement de "outrepasser les paramètres de sécurité de base". Pour pouvoir l'activer, il faut d'abord avoir demander UniversalPreferencesRead et UniversalPreferencesWrite. Malgré les nombreuses recherches que j'ai fait à ce sujet et les nombreux tests que j'ai réalisé, je n'ai pas réussi à trouver une situation où CapabilityPreferencesAccess est nécessaire. En effet, les situations où je l'ai testé ont tout de même provoquer une erreur de sécurité.(si vous avez une preuve du contraire, merci de me le dire)

UniversalFileRead

UniversalFileRead permet de lire ou ouvrir des fichiers en local (des fichiers sur votre ordinateur) ou plus officiellement de "Lire et récupérer des fichiers locaux". Cela peut servir par exemple à récupérer la vraie valeur d'un. Sans l'autorisation, seul le nom du fichier sera renvoyé et non son adresse. Ce petit exemple nous le prouve :

<html>
<head>
<title>Exemple : Connaître la vraie valeur d'un champ Parcourir</title>
Modifier la valeur pour voir l'exemple : 
<script type="application/javascript">
function RecevoirValeur(element){
if(window.netscape){
try{

alert(element.value);
netscape.security.PrivilegeManager.enablePrivilege('UniversalFileRead');
alert(element.value);

}
catch(e){
alert('Non-autorisé');
}
}
else{
alert('Vous ne supportez pas les privilèges');
}

}
</script>
</html>

Dans l'exemple, lorsque la valeur de l' est modifié, on affiche sa valeur, puis on demande un privilège, puis on la réaffiche. Vous voyez la différence ?

Autres valeurs

Lorsque d'autres valeurs sont demandés, aucune erreur ne se produit. La valeur de la demande de permission est "Inconnu : ***" où *** est le nom du faux privilège demandée. Auparavant, il existait le privilège UniversalSendMail qui permettait d'envoyer un e-mail à l'usager. Plus spécifiquement, il permettait d'envoyer un formulaire à une adresse commençant par "mailto:". Ce privilège n'est plus supporté (ni par Firefox 3, ni par la dernière version de Netscape ^^) . Il existait aussi UniversalBrowserAccess , qui semblait faire la même chose que ses deux frères. Il a connu le même sort. Au cours de mes recherches, j'ai découvert plusieurs privilèges autres que ceux présentés. Seulement, à l'exception de UniversalSedMail et de UniversalBrowserAccess aucun n'est documenté et aucun n'est supporté.

Astuce

Ceci est une astuce peu connue que j'ai trouvé lors de la lecture d'un site en portugais. Il est possible de remplacer :

netscape.security.PrivilegeManager.enablePrivilege('UniversalPreferencesWrite')
netscape.security.PrivilegeManager.enablePrivilege('CapabilityPreferencesAccess')

par

netscape.security.PrivilegeManager.enablePrivilege('UniversalPreferencesWrite CapabilityPreferencesAccess')

Il est donc possible de demander plusieurs privilèges en les séparant par un espace. Le message affiché est alors :

Modifier les paramètres de l'application
Outrepasser les paramètres de sécurité de base

Cela réduira le nombre de code et surtout, le nombre de demande. Fin de la géante parenthèse (^^) et retournons aux méthodes.

Retour aux méthodes

Je retourne aux méthodes et pourtant, j'imagine qu'à l'aide de la géante parenthèse, vous avez compris le concept. Voici tout de même 2 exemples pour les fonctions disablePrivilege et revertPrivilege :

<html>
<head>
<title>Exemple : Avoir le plein écran</title>
<script type="application/javascript">
if(window.netscape){
try{
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserWrite');
window.fullScreen=true;
netscape.security.PrivilegeManager.disablePrivilege('UniversalBrowserWrite');
window.fullScreen=false;
}
catch(e){
alert('Non-autorisé');
}
}
else{
alert('Vous ne supportez pas les privilèges');
}
</script>
</html>

et pour revertPrivilege :

<html>
<head>
<title>Exemple : Avoir le plein écran</title>
<script type="application/javascript">
if(window.netscape){
try{
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserWrite');
window.fullScreen=true;
netscape.security.PrivilegeManager.revert Privilege('UniversalBrowserWrite');
window.fullScreen=false;
}
catch(e){
alert('Non-autorisé');
}
}
else{
alert('Vous ne supportez pas les privilèges');
}
</script>
</html>

Juste un petit rappel (résumé) pour navigator.preference() . C'est une fonction qui peut agir de deux façons :

  • Avec UN paramètre :

Retourne la valeur de la préférence passer en paramètre. Le nom de la préférence peut être trouvé sur la page about:config

  • Avec DEUX paramètres :

Modifie la valeur de la préférence passer dans le premier paramètre pour la valeur du deuxième paramètre. Le nom de la préférence peut être trouvé sur la page about:config

Pour utiliser navigator.preference(), il faut avoir demander l'un des privilèges suivants : UniversalPreferences Read ou UniversalPreferencesWrite .

Quelle utilité ?

Quelle utilité y a-t-il a ajouté une fonction que l'utilisateur peut reproduire, qui demande une confirmation et qui n'est compatible qu'avec Firefox ? Tout simplement à rendre la vie de l'utilisateur plus facile. Ainsi, il n'aura plus à jouer avec about:config, il n'aura qu'à cliquer sur un bouton et valider la demande. Un exemple concret ?

Pour utiliser le presse-papier pour copier un code sur CodeS-SourceS sur Firefox, il faut aller soit-même dans about:config et modifier la clé signed.applets.codebase_principal_support . Un code comme celui-ci ferait la même chose mais en plus rapide :

<html>
<head>
<title>Exemple pour CodeS-SourceS</title>
<script type="application/javascript">
if(window.netscape){
try{
netscape.security.PrivilegeManager.enablePrivilege('UniversalPreferencesWrite');
navigator.preference('signed.applets.codebase_principal_support',true)
alert(' Copier/Coller autorisé')
}
catch(e){
alert('Non-autorisé');
}
}
else{
alert('Vous ne supportez pas les privilèges');
}
</script>
</html>

D'ailleurs, mon exemple de copier/coller dans la section UniversalXPConnect est tiré de CodeS-SourceS ( fichier CSScriptHandler.cshx, ligne 139-140 ) qui est d'ailleurs le seul site à grand public où j'ai pu trouvé les privilèges de Firefox. Et d'ailleurs c'est une extraordinaire idée ! Même si les privilèges ne sont pas compatibles avec tous les navigateurs, alors même augmenter l'expérience de navigation de seulement les utilisateurs de Firefox est super.

Mes Recommandations

Bon, mes recommandations. Je ne suis pas un programmeur professionnel, plutôt amateur mais je pense que mes très nombreuses lectures sur le sujets dans des langues très variés (français, anglais, espagnol, portugais) m'a permis d'apprendre sur le sujet assez pour devenir un petit "spécialiste" des privilèges dans Firefox. Mais j'ai sûrement oublié de vous précisez ceci ou cela dans ce tutoriel (qui est d'ailleurs plutôt une documentation) et si vous remarquez un oubli, merci de me le précisez.

Je trouve que les privilèges servent à paliers des manques dans Firefox. Maintenant que de nombreuses applications web apparaissent, Javascript doit offrir des fonctions plus poussés et c'est ce que Firefox offre. Internet Explorer permet de faire de même, mais les fonctions disponibles sont plus dispersés et non réunis dans deux seuls fonctions comme dans Firefox. Seulement les fonctions d'Internet Explorer (par exemple, setHomePage() ) sont beaucoup plus connus et beaucoup plus utilisés que les privilèges de Firefox.

Voici donc ce que je vous recommande : Utilisez les privilèges de Firefox dans vos applications mais comme complément . Votre script ne doit pas reposer sur les privilèges mais plutôt améliorer l'expérience de navigation des utilisateurs de Firefox. Vos visiteurs vous en seront reconnaissants.

Ce document intitulé « Les privilèges dans firefox » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Rejoignez-nous