Les pages « actives »

Nous allons maintenant jouer un peu avec quelques possibilités qui font parfois peur…

Vous divulguez plus d'informations que vous ne croyez...

Voici un exemple simple de ce qu'un serveur HTTP reçoit de votre part comme informations « cachées » et qu'il est donc capable d'exploiter, comme ici par exemple juste pour vous les afficher:

echo '<table class="inline">'; echo '<tbody>'; echo '<tr class="row0"><th class="col0 rightalign">Votre Adresse IP (publique)</th><td>', getenv(REMOTE_ADDR), '</td></tr>'; echo '<tr class="row1"><th class="col0 rightalign">Le nom de votre machine telle qu\'elle est connue sur le Net</th><td>', gethostbyaddr(getenv(REMOTE_ADDR)), '</td></tr>'; echo '<tr class="row2"><th class="col0 rightalign">La façon dont vous vous présentez en tant que client HTTP</th><td>', getenv(HTTP_USER_AGENT), '</td></tr>'; echo '<tr class="row3"><th class="col0 rightalign">La version de protocole HTTP utilisée</th><td>', getenv(SERVER_PROTOCOL), '</td></tr>'; echo '<tr class="row4"><th class="col0 rightalign">Les types MIME</th><td>', str_replace(",",",<br>",getenv(HTTP_ACCEPT)), '</td></tr>'; echo '<tr class="row5"><th class="col0 rightalign">Le document qui vous a conduit jusqu\'ici</th><td>', getenv(HTTP_REFERER), '</td></tr>'; echo '</tbody>'; echo '</table>';

Miracle ?

Pas le moins du monde. Cette page est dynamique. Les informations qu'elle contient sont construites à la volée par le serveur, avant de vous l'envoyer. La technologie utilisée est ici PHP. Les informations affichées ci-dessus sont obtenues à partir des variables d'environnement que votre navigateur envoie à chaque commande GET.

PHP n'est qu'un moyen de construire une page HTML dynamique qui vous renvoie ces informations, ça aurait aussi pu être fait avec un script CGI (dans les limites de ce que permet l'hébergeur).

Si vous regardez le « source » de cette page, vous n'y trouverez que du HTML

Les formulaires...

Les formulaires ont pour but de permettre au client d'envoyer des données au serveur. A charge pour lui de les traiter correctement. Leur emploi va du simple « log in » à la composition de documents très sophistiqués, et hélas aussi parfois, à l'envoi d'informations qui ont été récupérées sur votre système à votre insu.

Un formulaire peut envoyer ses données de deux manières :

Par la méthode « GET »

Avec cette méthode, les données sont envoyées dans l'URI de la page qui sera appelée lorsque vous cliquerez sur « envoyer ».

Dans le formulaire ci-dessous :

  • Le champ de saisie de texte s'appelle « saisie1 ».
  • Le bouton s'appelle « B1 ».

mettez là dedans ce qu'il vous passe par la tête (40 caractères maximum) :
Puis, cliquez sur le bouton « Demander »

Par la méthode « POST ».

A première vue, les données sont envoyées de façon « invisible ».

Dans le formulaire ci dessus :

  • Le champ de saisie de texte s'appelle « saisie2 ».
  • Le bouton s'appelle « B2 ».

remettez là dedans ce qu'il vous passe par la tête (40 caractères maximum) :
Puis, cliquez sur le bouton « Poster »

Le délicat cas des « cookies »

Un cookie, c'est un petit fichier qu'un serveur HTTP peut écrire (et lire) sur votre machine par l'intermédiaire de votre navigateur. L'objectif initial n'est en rien malicieux et peut même vous rendre service. Nous l'avons déjà vu, HTTP ne gère pas le concept de session. Une session, c'est une période pendant laquelle un certain contexte reste constant, même si vous y faites des choses différentes. Par exemple, vous entrez dans un lieu protégé par une porte fermant à clé. Vous ouvrez cette porte au moyen de la clé. Une fois rentré dans ce lieu, vous pouvez y faire tout ce qui est autorisé et vous n'aurez plus besoin de la clé, jusqu'à ce que vous soyez sorti.

HTTP ne sait pas faire cela et ne conserve aucune mémoire du passé si ce n'est l'URI de la page d'où vous venez. C'est un peu faible, surtout si l'on doit gérer des identifications de personnes, par exemple. Dans ces cas là, un cookie permettra de contourner le problème en permettant au serveur de retrouver à chaque page des informations écrites dans ce cookie.

Un exemple trivial

Le formulaire suivant vous permet de saisir une information dans un formulaire et de l'envoyer avec la méthode POST (ça aurait été pareil avec la méthode GET, d'ailleurs).

La différence par rapport aux exemples précédents, c'est que la page qui va être appelée à l'envoi des données de ce formulaire va écrire un cookie contenant cette donnée sur votre machine (sauf si vous avez interdit à votre navigateur d'accepter les cookies).

mettez dans cette case une information quelconque (40 caractères maximum) :
Puis, cliquez sur le bouton « Envoyer »

Explications

Comme vous en avez l'habitude, cette trace correspond à un exemple exécuté sur mon installation et non à la manipulation que vous êtes en train de faire…

Ce n'est pas la méthode POST employée dans le formulaire qui va écrire le cookie dans la mémoire de votre navigateur, mais bien la page que ce formulaire invoque, form_cookie1.php dans notre cas.
Commençons par un aperçu sommaire

No. Time      Source        Destination   Proto Info
  La page des exemples est appelée...
  8 0.443083  192.168.0.10  192.168.0.251 HTTP  GET /http/exemple1.php HTTP/1.1
  9 0.443425  192.168.0.251 192.168.0.10  TCP   80 > 2349 [ACK]
  Elle rentre...
 10 0.470220  192.168.0.251 192.168.0.10  HTTP  HTTP/1.1 200 OK
 11 0.471471  192.168.0.251 192.168.0.10  HTTP  Continuation
 12 0.471874  192.168.0.10  192.168.0.251 TCP   2349 > 80 [ACK]
 13 0.473661  192.168.0.251 192.168.0.10  HTTP  Continuation
 14 0.474914  192.168.0.251 192.168.0.10  HTTP  Continuation
 15 0.474943  192.168.0.10  192.168.0.251 TCP   2349 > 80 [ACK]
 16 0.476205  192.168.0.251 192.168.0.10  HTTP  Continuation
 17 0.476246  192.168.0.251 192.168.0.10  HTTP  Continuation
 18 0.476730  192.168.0.10  192.168.0.251 TCP   2349 > 80 [ACK]
 Le formulaire avec la valeur du cookie est envoyé...
 19 8.621094  192.168.0.10  192.168.0.251 HTTP  POST /http/post_cookie1.php HTTP/1.1
 La première page de réponse est envoyée par le serveur (c'est elle qui écrit le cookie).
 20 8.642651  192.168.0.251 192.168.0.10  HTTP  HTTP/1.1 200 OK
 21 8.750822  192.168.0.10  192.168.0.251 TCP   2349 > 80 [ACK]
 La page de vérification du cookie est demandée par un GET "normal"...
 22 11.101585 192.168.0.10  192.168.0.251 HTTP  GET /http/post_cookie2.php HTTP/1.1
 Elle est envoyée par le serveur.
 23 11.122099 192.168.0.251 192.168.0.10  HTTP  HTTP/1.1 200 OK
 24 11.258788 192.168.0.10  192.168.0.251 TCP   2349 > 80 [ACK]

Plus en détails...
  • La trame 8 ne présente pas d'intérêt particulier, elle représente l'appel de la page d'exemples “exemple1.php”.
  • Les trames 10 à 17 représentent quant à elles l'arrivée de cette page. Elle est longue et nécessite plusieurs trames.
  • La trame 19 commence à nous intéresser. Elle correspond à l'envoi du formulaire relatif aux cookies:

Frame 19 (439 on wire, 439 captured)
...
Hypertext Transfer Protocol
    POST /http/post_cookie1.php HTTP/1.1\r\n
    Accept: */*\r\n
    Referer: http://gw2.maison.mrs/http/exemple1.php\r\n
    Accept-Language: fr\r\n
    Content-Type: application/x-www-form-urlencoded\r\n
    Accept-Encoding: gzip, deflate\r\n
    User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\r\n
    Host: gw2.maison.mrs\r\n
    Content-Length: 25\r\n
    Connection: Keep-Alive\r\n
    Cache-Control: no-cache\r\n
    \r\n

    Data (25 bytes)
0000  73 61 69 73 69 65 33 3d 63 6f 6f 6b 69 65 26 42   saisie3=cookie&B
0010  33 3d 45 6e 76 6f 79 65 72                        3=Envoyer       

  • La trame 20 est intéressante parce qu'elle met en évidence l'envoi du cookie du serveur au client :

Frame 20 (1473 on wire, 1473 captured)
...
Hypertext Transfer Protocol
    HTTP/1.1 200 OK\r\n
    Date: Sun, 21 Apr 2002 13:11:11 GMT\r\n
    Server: Apache-AdvancedExtranetServer/1.3.22 
            (Mandrake Linux/1.1mdk) PHP/4.0.6 mod_ssl/2.8.5 OpenSSL/0.9.6b\r\n
    X-Powered-By: PHP/4.0.6\r\n
    Set-Cookie: VotreCookie=cookie; expires=Sun, 21-Apr-02 13:13:11 GMT\r\n
    Le cookie a un identificateur : VotreCookie et une valeur : cookie
    Keep-Alive: timeout=15, max=99\r\n
    Connection: Keep-Alive\r\n
    Transfer-Encoding: chunked\r\n
    Content-Type: text/html\r\n
    \r\n

    Data (1051 bytes)
Vient ensuite le document lui-même...
0000  34 30 66 0d 0a 3c 68 74 6d 6c 3e 0d 0a 0d 0a 3c   40f..<html>....<
0010  68 65 61 64 3e 0d 0a 3c 6d 65 74 61 20 68 74 74   head>..<meta htt
...

  • La trame 22 montre comment votre navigateur renvoie docilement votre cookie au serveur à chaque requête qu'il effectuera sur ce serveur.
    Rappelons que la page “post_cookie1.php” ne présente aucun formulaire, aucun champ de saisie ni rien qui puisse vous laisser penser que la prochaine requête va transmettre des informations au serveur.

Frame 22 (481 on wire, 481 captured)
...
Hypertext Transfer Protocol
    GET /http/post_cookie2.php HTTP/1.1\r\n
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*\r\n
    Referer: http://gw2.maison.mrs/http/post_cookie1.php\r\n
    Accept-Language: fr\r\n
    Accept-Encoding: gzip, deflate\r\n
    User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\r\n
    Host: gw2.maison.mrs\r\n
    Connection: Keep-Alive\r\n
    Cookie: VotreCookie=cookie\r\n
    Voilà votre cookie qui est envoyé à votre insu.
    \r\n

  • La trame 23 présente un intérêt tout de même, parce qu'elle montre que le cookie n'apparait pas directement.
    Entendez par là que le serveur ayant reçu ce cookie va en faire ce qu'il veut. Ici, il se contente d'en afficher le contenu dans la page. C'est une page active, construite par PHP. Rappelez-vous que votre navigateur, dans ce cas, reçoit du HTML tout ce qu'il y a de plus « passif ». Pas de script si l'auteur n'en a pas décidé autrement.
    Tout navigateur capable d'afficher du HTML affichera correctement cette page, même s'il ne sait absolument pas traiter les scripts.

Frame 23 (1127 on wire, 1127 captured)
...
Hypertext Transfer Protocol
    HTTP/1.1 200 OK\r\n
    Date: Sun, 21 Apr 2002 13:11:14 GMT\r\n
    Server: Apache-AdvancedExtranetServer/1.3.22 (Mandrake Linux/1.1mdk) PHP/4.0.6 mod_ssl/2.8.5 OpenSSL/0.9.6b\r\n
    X-Powered-By: PHP/4.0.6\r\n
    Keep-Alive: timeout=15, max=98\r\n
    Connection: Keep-Alive\r\n
    Transfer-Encoding: chunked\r\n
    Content-Type: text/html\r\n
    \r\n

    Data (774 bytes)
0000  32 66 61 0d 0a 3c 68 74 6d 6c 3e 0d 0a 0d 0a 3c   2fa..<html>....<
0010  68 65 61 64 3e 0d 0a 3c 6d 65 74 61 20 68 74 74   head>..<meta htt
0020  70 2d 65 71 75 69 76 3d 22 43 6f 6e 74 65 6e 74   p-equiv="Content
0030  2d 4c 61 6e 67 75 61 67 65 22 20 63 6f 6e 74 65   -Language" conte
0040  6e 74 3d 22 66 72 22 3e 0d 0a 3c 6d 65 74 61 20   nt="fr">..<meta 
0050  68 74 74 70 2d 65 71 75 69 76 3d 22 43 6f 6e 74   http-equiv="Cont
0060  65 6e 74 2d 54 79 70 65 22 20 63 6f 6e 74 65 6e   ent-Type" conten
0070  74 3d 22 74 65 78 74 2f 68 74 6d 6c 3b 20 63 68   t="text/html; ch
0080  61 72 73 65 74 3d 77 69 6e 64 6f 77 73 2d 31 32   arset=windows-12
0090  35 32 22 3e 0d 0a 3c 6d 65 74 61 20 6e 61 6d 65   52">..<meta name
00a0  3d 22 47 45 4e 45 52 41 54 4f 52 22 20 63 6f 6e   ="GENERATOR" con
00b0  74 65 6e 74 3d 22 4d 69 63 72 6f 73 6f 66 74 20   tent="Microsoft 
00c0  46 72 6f 6e 74 50 61 67 65 20 34 2e 30 22 3e 0d   FrontPage 4.0">.
00d0  0a 3c 6d 65 74 61 20 6e 61 6d 65 3d 22 50 72 6f   .<meta name="Pro
00e0  67 49 64 22 20 63 6f 6e 74 65 6e 74 3d 22 46 72   gId" content="Fr
00f0  6f 6e 74 50 61 67 65 2e 45 64 69 74 6f 72 2e 44   ontPage.Editor.D
0100  6f 63 75 6d 65 6e 74 22 3e 0d 0a 3c 74 69 74 6c   ocument">..<titl
0110  65 3e 52 e9 73 75 6c 74 61 74 20 64 65 20 6c 61   e>R.sultat de la
0120  20 6d 61 6e 69 70 3c 2f 74 69 74 6c 65 3e 0d 0a    manip</title>..
0130  3c 21 2d 2d 6d 73 74 68 65 6d 65 2d 2d 3e 3c 6c   <!--mstheme--><l
0140  69 6e 6b 20 72 65 6c 3d 22 73 74 79 6c 65 73 68   ink rel="stylesh
0150  65 65 74 22 20 68 72 65 66 3d 22 66 69 6c 65 3a   eet" href="file:
0160  2f 2f 2f 47 3a 2f 44 4f 43 55 4d 45 7e 31 2f 63   ///G:/DOCUME~1/c
0170  68 72 69 73 2f 4c 4f 43 41 4c 53 7e 31 2f 54 65   hris/LOCALS~1/Te
0180  6d 70 2f 46 72 6f 6e 74 50 61 67 65 54 65 6d 70   mp/FrontPageTemp
0190  44 69 72 2f 6d 73 74 68 65 6d 65 2f 74 61 62 73   Dir/mstheme/tabs
01a0  2f 74 61 62 73 31 31 31 31 2e 63 73 73 22 3e 0d   /tabs1111.css">.
01b0  0a 3c 6d 65 74 61 20 6e 61 6d 65 3d 22 4d 69 63   .<meta name="Mic
01c0  72 6f 73 6f 66 74 20 54 68 65 6d 65 22 20 63 6f   rosoft Theme" co
01d0  6e 74 65 6e 74 3d 22 74 61 62 73 20 31 31 31 31   ntent="tabs 1111
01e0  2c 20 64 65 66 61 75 6c 74 22 3e 0d 0a 3c 6d 65   , default">..<me
01f0  74 61 20 6e 61 6d 65 3d 22 4d 69 63 72 6f 73 6f   ta name="Microso
0200  66 74 20 42 6f 72 64 65 72 22 20 63 6f 6e 74 65   ft Border" conte
0210  6e 74 3d 22 6e 6f 6e 65 22 3e 0d 0a 3c 2f 68 65   nt="none">..</he
0220  61 64 3e 0d 0a 0d 0a 3c 62 6f 64 79 3e 0d 0a 0d   ad>....<body>...
0230  0a 3c 68 31 3e 52 e9 73 75 6c 74 61 74 20 64 65   .<h1>R.sultat de
0240  20 6c 61 20 6d 61 6e 69 70 3a 3c 2f 68 31 3e 0d    la manip:</h1>.
0250  0a 3c 70 3e 0d 0a 56 6f 74 72 65 20 63 6f 6f 6b   .<p>..Votre cook
0260  69 65 20 65 78 69 73 74 65 20 74 6f 75 6a 6f 75   ie existe toujou
0270  72 73 20 65 74 20 63 6f 6e 74 69 65 6e 74 20 6c   rs et contient l
0280  61 20 76 61 6c 65 75 72 20 3a 20 3c 62 3e 3c 75   a valeur : <b><u
0290  3e 63 6f 6f 6b 69 65 3c 2f 75 3e 3c 2f 62 3e 0d   >cookie</u></b>.
02a0  0a 3c 2f 70 3e 0d 0a 0d 0a 3c 68 32 3e 4d 61 69   .</p>....<h2>Mai
02b0  73 20 71 75 65 20 73 27 65 73 74 2d 69 6c 20 70   s que s'est-il p
02c0  61 73 73 e9 20 64 61 6e 73 20 74 6f 75 74 20 e7   ass. dans tout .
02d0  61 20 3f 3c 2f 68 32 3e 0d 0a 3c 70 3e 26 6e 62   a ?</h2>..<p>&nb
02e0  73 70 3b 3c 2f 70 3e 0d 0a 0d 0a 3c 2f 62 6f 64   sp;</p>....</bod
02f0  79 3e 0d 0a 0d 0a 3c 2f 68 74 6d 6c 3e 0d 0a 0d   y>....</html>...
0300  0a 30 0d 0a 0d 0a                                 .0....

Conclusions

Nous avons vu quelques exemples de ce que l'on peut faire avec :

  • Un client qui envoie des données volontairement ou non, à un serveur.
  • Un serveur qui exploite ces données au moyen de scripts, ici en PHP.

Nous n'avons pas vu ce que pourrait faire un script CGI, mais ce serait du même ordre. Toutes ces démonstrations sont donc axées sur du « server side ». Le client envoie les données et reçoit du HTML statique. C'est le serveur qui traite les données reçues et agit en fonction.

Dans tout ce que nous avons vu ici, le « dynamisme » des pages venait exclusivement du serveur, et le client se contente d'envoyer des requêtes et des données pour voir le contenu des pages se modifier. La page suivante va vous donner quelques exemples simples de Java scripts qui s'exécutent côté client, donc sur votre machine.