Connexion
Ces billets correspondent à un filtre sur: web2.0

Firefox 3 and protocol handlers - Part 2 - ExtApp

Le précédent article s'était arrêté à présenter l'application Web de principe du gestionnaire de protocoles de Firefox 3. L'article que vous êtes en train de lire va lui s'attacher à vous permettre d'utiliser une application externe pour un protocole donné.

Un exemple d'application externe

Je vais présenter ici un petit exemple d'application en Python qui permet d'écrire dans un fichier journal (ou 'log') le contenu de la valeur passée via l'appel du protocole. Dans cet exemple le protocole utilisée est "mycall" (l'idée est de simuler la création d'un softphone appelé par une interface de click-to-call).

    #!/usr/bin/python
#-*- coding: utf-8 -*-

# On importe deux bibliothèques utiles pour la suite
import sys
from datetime import datetime

# On met la date dans une variable pour tracer les résultats
date = datetime.now()

# Ici ça se complique un peu. Comme le gestionnaire de protocole
# de firefox donne en argument l'ensemble de la chaine 'href',
# nous allons enlever la chaine 'mycall:' pour ne conserver que
# la valeur décimale de cette chaine
arg = sys.argv[1][7:]

# On ouvre en écriture le fichier journal
# ('a' pour écrire à la suite)
filout = open('/path/to/log/file/calltest.log','a')

# On écrit la valeur envoyée précédée de la date
filout.write('%d/%d/%d %d:%d - Voici l\'argument donné : ' % (date.day, 
                                                              date.month,
                                                              date.year,
                                                              date.hour,
                                                              date.minute))
filout.write(arg + '\n')

# On ferme le fichier
filout.close()

On donne les droits d'exécution à ce script :

    chmod +x /path/to/ext/app/call.py

L'application web

Il est maintenant temps de créer l'interface web de 'click-to-call' sur laquelle figurera le lien vers le protocole 'mycall'. Pour ceux qui ont lu l'article précédent, vous remarquerez que c'est encore plus simple.

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
  <title>Web Protocol Handler Sample - Register</title>
</head>
<body>
  <h1>External protocol handler sample</h1>
  <p>This web page will install an external protocol handler for the <code>mycall:</code> protocol.</p>

  <p>Hey have you seen <a href="mycall:874781">this</a> before?</p>
</body>
</html>

Configurer firefox

Si l'interface web est encore plus simple, il faut toutefois configurer un peu Mozilla Firefox.

About:config

Pour accéder au registre de configuration de Firefox, il faut entrer l'adresse suivante dans la barre d'adresse.

    about:config
  • Ensuite, il faut créer une 'nouvelle' 'valeur booléenne' (via un click droit) qui portera le nom suivant: "network.protocol-handler.expose.mycall" et mettre la valeur à "true". Cette valeur permettra d'autoriser l'utilisation de ce nouveau protocole.
  • Un second couple nom + valeur est à créer afin de pouvoir éviter un avertissement lors de l'utilisation d'une application externe: "network.protocol-handler.warn-external.mycall" qui prendra la valeur "false".

1er essai

Si vous êtes sur un système qui supporte Bash (Linux, Mac OS, BSD...), vous pouvez lancer un 'tail -f' sur le fichier journal afin d'en suivre l'évolution. Cela nécessite tout de même que le fichier existe avant. Si ce n'est pas le cas, il suffit de le créer avec :

    touch /path/to/log/file/calltest.log

On lance la surveillance du fichier :

    tail -f /path/to/log/file/calltest.log

On charge la page HTML qui contient le lien 'href' et on suit le lien. Une fenêtre s'affiche alors, vous permettant de choisir l'application à utiliser. Il suffit de choisir celle que vous avez créé plus haut et de cocher (si vous le souhaitez) 'se souvenir' afin de ne plus avoir à le faire ensuite.

À chaque clic, vous ajoutez normalement une ligne dans le fichier journal avec la valeur passée suite à 'mycall:'. À vous d'être imaginatif pour utiliser cette astuce au mieux.

Commentaires: 0 | Buzz it!

Firefox 3 and protocol handlers - Part 1 - WebApp

J'initie ici un nouveau couple (ou plus on verra) d'articles concernant la gestion des 'protocol-handlers' avec firefox 3. La première partie présentera cette fonctionnalité ainsi que son application au sein d'une application web. La seconde, conduira à la création d'un petit logiciel externe en python qui utilisera les mêmes astuces pour par exemple proposer à l'utilisateur d'appeler avec son softphone depuis une interface web.

Présentation des protocol handlers

Deux exemples valent mieux qu'une longue explication...

Les liens mail

Il est assez courant sur le web de croiser des sites qui proposent des liens pour envoyer un email au webmaster ou à n'importe quelle autre personne. Ces liens si vous regardez le code source de la page sont de type :

mailto:mabelle.adresse@mail.com

Si vous cliquez sur un de ces liens, normalement, votre logiciel de mail favori va s'ouvrir et vous proposer de rédiger un mail pour la personne indiquée (dont le nom est automatiquement placé dans le champ "à :". Vous avez ici une application des protocol handlers.

Les liens apt:// d'Ubuntu

La documentation d'Ubuntu propose de nombreux liens de la forme suivante :

	apt://un-logiciel

Les utilisateurs de cette distribution (comme moi) savent que ce type de lien permet d'installer des paquets (librairies ou logiciels) via un simple clic. Une fois le lien cliqué, une application de votre ordinateur recherche l'application dans les dépôts disponible et l'installe si il est disponible. Vous l'aurez compris par vous même, c'est une autre application de l'utilisation des protocol handlers.

Utiliser une application web

L'exemple suivant vise à proposer au sein d'une page web A un lien de type :

	test:CeciEstUnTest

Ce lien redirigera l'utilisateur sur une page B qui utilisera la valeur donnée.

Cet exemple ne vous parle peut être pas trop, mais vous pouvez très bien imaginer qu'il s'agit de liens mail qui pointent vers une application web de lecture/écriture de mail.

Firefox propose depuis sa version 3 une fonction de l'objet "navigator" qui permet à une application web d'enregistrer son propre gestionnaire de protocole :

	window.navigator.registerProtocolHandler(protocole, uri, titre);
  • protocole : chaine de caractère pour le protocole à gérer (ex: test)
  • uri : chaine de caractère représentant l'URL à appeler au clic. %s peut être utiliser pour passer la valeur en paramètre de cette url. (ex: http://monexemple.com/application?value=%s)
  • titre : Titre du gestionnaire (indication utilisateur). (ex: Mon gestionnaire de Test)

Limitations

  • Un gestionnaire de protocole ne peut être enregistré que pour le même domaine que l'application qui l'enregistre. Ceci afin d'éviter les problème de sécurité ou de cross scripting.
  • La valeur transmise à l'aide de '%s' est l'ensemble du contenu de l'attribut 'href' de la balise 'a'. Il faut donc que le gestionnaire de protocole fasse le tri dans cette valeur afin d'utiliser la valeur qui suis le protocole.

Enregistrer un nouveau gestionnaire de protocole

Voici un exemple concert que vous pouvez essayer chez vous :

	<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="fr">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Protocol Handler - test:</title>
    <script type="text/javascript">
    	navigator.registerProtocolHandler("test", 
                                                              "http://monexemple.com/application.php?value=%s",
                                                              "Mon gestionnaire de Test");
  </script>
</head>
<body>
	<h1>Protocol Handler - test:</h1>
  	<p>Dans la partie 'script', cette page va enregistrer un nouveau gestionnaire de code pour les liens en 
<code>test:</code>.</p>
  	<p>Il sera ensuite possible d'utiliser ce lien : <a href="test:Pouf pastèque">Lien exemple</a>.</p>
</body>
</html>

Un gestionnaire très simplifié

Il ne reste plus qu'à créer un handler associé (ici en php pour simplifier) qui utilisera la valeur passée en paramètre :

	<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="fr">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Protocol Handler - test: - Handler</title>
</head>
<body>
	<h1>Protocol Handler - test: - Handler</h1>
	<h1>Cette page est affichée lorsque vous utilisez un lien de type : <pre>test:</pre></h1>
  	<blockquote>
  		<pre><?php if ( isset ( $_GET["value"] ) ) {
                       echo(urldecode($_GET["value"]));
                   } else {
                   	   echo("nothing");
                   }
             ?></pre>
  	</blockquote>
</body>
</html>

Des liens qui peuvent être utiles

Commentaires: 0 | Buzz it!

JavaScript Object Notation et sécurité

Le JSON

Le JSON (ou JavaScript Object Notation) est un format de données au format texte qui est décrit dans la RFC 4627. Très utilisé avec le cadre des applications Web2.0 et AJAX, il présente plusieurs avantages:

  • Lisibilité : Peu verbeux, il est facilement lisible pas un être humain.
  • Performances : Comme il utilise une représentation d'objets et une notation empruntés à JavaScript, il s'avère plus facilement et rapidement utilisable dans le contexte d'un traitement par ce langage.
  • Simple : La syntaxe réduite et les types de donnés simples en font un format de données facile à apprendre.

Voici un exemple de données (un menu sous forme de liste d'actions simples):

{"liste": { "id": "liste", "value": "Menu", "popup": { "menuitem": [ {"value": "action 1", "onclick": "MyFunction1()"}, {"value": "action 2", "onclick": "MyFunction2()"}, {"value": "action 3", "onclick": "MyFunction3()"} ] } }}

Et la sécurité dans tous ça

L'utilisation d'une structure de données JSON dans un corps de programme JavaScript est faite par l'utilisation de la fonction :

eval('('+donnees_json+')');

Avec cette méthde, les données sont transformées en objet(s) natif(s) et ainsi utilisables. Mais les données peuvent aussi contenir du code JavaScript et ainsi, celui-ci risque de s'exécuter lors de l'évaluation des données. C'est un problème de sécurité très grâve qui entrave encore bien souvent le déployement de ce format de données en remplacement du concurrent XML.

Des remèdes

La démocratisation et le formidable essor des Frameworks dits Web2.0 au cours de ces dernières années ont contribué à proposer des solutions pour contourner les problèmes de sécurité de ce format pourtant bien utile au demeurant.

Pour ma part j'ai suivi un peu le développement du framework Dojo Toolkit et les essais plus ou moins fructueux pour combattre cette limitation.

On commente

Une des recommandations utilisées notamment pour la version 1.0 de Dojo, était de commenter les données afin d'éviter l'exécution du code qui pouvait y être inclus :

/* {"liste": { "id": "liste", "value": "Menu", "popup": { "menuitem": [ {"value": "action 1", "onclick": "MyFunction1()"}, {"value": "action 2", "onclick": "MyFunction2()"}, {"value": "action 3", "onclick": "MyFunction3()"} ] } }} */

Il s'avère que cette solution est facilement contournable puisqu'il suffit à un attaquant d'injecter des données qui referme ce commentaire avant d'inclure du code à exécuter et de réouvrir un commentaire pour rendre le contenu valide. Ce point a été soulevé et très clairement expliqué dans un ticket du Trac Dojo par Kriszyp.

On préfixe à présent

Kriszyp lors de son explication de la vulnérabilité de la méthode "json-commenting", propose de préfixer les données à l'aide d'une simple petite chaine:

{} &&

Ce préfixe a pour but de rendre invalide (du point de vue de la syntaxe) un éventuel script au sein des données JSON et de ne pas contraindre de trop l'utilisation des données (éviter un parsing).

Du coup, depuis la version 1.2 de Dojo, la recommandation est d'utiliser cette syntaxe :

{} && {"liste": { "id": "liste", "value": "Menu", "popup": { "menuitem": [ {"value": "action 1", "onclick": "MyFunction1()"}, {"value": "action 2", "onclick": "MyFunction2()"}, {"value": "action 3", "onclick": "MyFunction3()"} ] } }}

Conclusion

Il semble que cette méthode est la plus fiable et efficace connue à présent pour éviter le détournement ("hijacking" en anglais) de ce format de données qui a une place au soleil dans le monde du Web 2.0 en plein développement. Reste à surveiller l'émergence d'une réponse ou de technique de contournement afin de conserver la sécurité des applications et des données.

Commentaires: 0 | Buzz it!