Dans ce dernier chapitre, nous examinerons les aspects de sécurité de HTTP, notamment l'identification des utilisateurs, le fonctionnement de l'authentification HTTP et les raisons pour lesquelles certains scénarios nécessitent le protocole HTTPS (HTTP sécurisé). En cours de route, nous allons également apprendre un peu plus sur la gestion de l'état avec HTTP..
HTTP est un protocole sans état, ce qui signifie que chaque transaction demande-réponse est indépendante de toute transaction précédente ou future. Rien dans le protocole HTTP n'oblige un serveur à conserver des informations sur une requête HTTP. Tout ce que le serveur doit faire est de générer une réponse pour chaque demande. Chaque demande contiendra toutes les informations dont un serveur a besoin pour créer la réponse..
La nature sans état de HTTP est l’un des facteurs déterminants du succès du Web. Les services en couches que nous avons examinés au chapitre précédent, des services tels que la mise en cache, sont tous rendus possibles (ou au moins plus faciles), car chaque message contient toutes les informations nécessaires à son traitement. Les serveurs proxy et les serveurs Web peuvent inspecter, transformer et mettre en cache des messages. Sans la mise en cache, le Web ne pourrait pas s'adapter à la demande d'Internet..
Cependant, la plupart des applications et des services Web que nous construisons au-dessus de HTTP sont extrêmement dynamiques..
Une application bancaire voudra qu'un utilisateur se connecte avant de lui permettre de visualiser les ressources liées à son compte. Lorsque chaque demande sans état arrive pour une ressource privée, l'application veut s'assurer que l'utilisateur a déjà été authentifié. Un autre exemple est lorsque l'utilisateur veut ouvrir un compte et remplir des formulaires dans un assistant de trois pages. L’application voudra s’assurer que la première page de l’assistant est complète avant de permettre à l’utilisateur de soumettre la deuxième page..
Heureusement, il existe de nombreuses options pour stocker l’état dans une application Web. Une approche consiste à incorporer l'état dans les ressources transférées au client, de sorte que tout l'état requis par l'application sera renvoyé à la demande suivante. Cette approche nécessite généralement des champs de saisie masqués et fonctionne mieux pour les états de courte durée (comme l'état requis pour se déplacer dans un assistant de trois pages). L'intégration de l'état dans la ressource conserve tout l'état à l'intérieur des messages HTTP. Il s'agit donc d'une approche hautement évolutive, mais qui peut compliquer la programmation de l'application..
Une autre option consiste à stocker l'état sur le serveur (ou derrière le serveur). Cette option est requise pour un état qui doit durer longtemps. Supposons que l'utilisateur envoie un formulaire pour modifier son adresse électronique. L'adresse électronique doit toujours être associée à l'utilisateur pour que l'application puisse prendre la nouvelle adresse, la valider et la stocker dans une base de données, un fichier ou appeler un service Web pour permettre à une autre personne de s'enregistrer..
Pour le stockage côté serveur, de nombreux frameworks de développement Web tels que ASP.NET fournissent également un accès à une "session utilisateur". La session peut vivre en mémoire ou dans une base de données, mais un développeur peut stocker des informations dans la session et récupérer les informations à chaque demande ultérieure. Les données stockées dans une session sont étendues à un utilisateur individuel (en fait, à sa session de navigation) et ne sont pas partagées par plusieurs utilisateurs..
Le stockage de session a un modèle de programmation simple et ne convient que pour les états de courte durée, car le serveur doit finalement supposer que l'utilisateur a quitté le site ou fermé le navigateur et le serveur ignorera la session. Le stockage de session, s’il est stocké en mémoire, peut avoir un impact négatif sur l’évolutivité, car les demandes suivantes doivent aller au même serveur où se trouvent les données de la session. Certains équilibreurs de charge aident à prendre en charge ce scénario en mettant en œuvre des "sessions persistantes"..
Vous vous demandez peut-être comment un serveur peut suivre un utilisateur pour implémenter l'état de session. Si deux demandes arrivent sur un serveur, comment le serveur sait-il s'il s'agit de deux demandes émanant du même utilisateur ou s'il y a deux utilisateurs différents effectuant une seule demande??
Au tout début du Web, le logiciel serveur pouvait différencier les utilisateurs en regardant l'adresse IP d'un message de requête. De nos jours, toutefois, de nombreux utilisateurs vivent derrière des périphériques utilisant la traduction d'adresses réseau. Pour cette raison, entre autres, vous pouvez avoir plusieurs utilisateurs avec la même adresse IP. Une adresse IP n'est pas une technique fiable pour différencier les utilisateurs.
Heureusement, il existe des techniques plus fiables.
Les sites Web qui souhaitent suivre les utilisateurs se tournent souvent vers biscuits. Les cookies sont définis par RFC6265 (http://tools.ietf.org/html/rfc6265), et le présent RFC s'intitule à juste titre "Mécanisme de gestion d'état HTTP". Lorsqu'un utilisateur visite pour la première fois un site Web, celui-ci peut attribuer un cookie à son navigateur à l'aide d'un en-tête HTTP. Le navigateur sait alors envoyer le cookie dans les en-têtes de chaque requête supplémentaire qu’il envoie au site. En supposant que le site Web ait placé une sorte d'identifiant unique dans le cookie, le site peut désormais suivre un utilisateur au fur et à mesure qu'il fait des demandes et différencier un utilisateur d'un autre..
Avant d'entrer dans les détails de ce à quoi ressemblent les cookies et de leur comportement, il convient de noter quelques limitations. Premièrement, les cookies peuvent identifier les utilisateurs dans le sens où votre cookie est différent de mon cookie, mais les cookies n'authentifient pas les utilisateurs. Un utilisateur authentifié a généralement prouvé son identité en fournissant des informations d'identification telles qu'un nom d'utilisateur et un mot de passe. Les cookies dont nous parlons jusqu'à présent nous fournissent simplement un identifiant unique permettant de différencier un utilisateur d'un autre et de suivre un utilisateur au fur et à mesure des demandes adressées au site..
Deuxièmement, comme les cookies peuvent suivre ce que fait un utilisateur, ils soulèvent des problèmes de confidentialité dans certains milieux. Certains utilisateurs désactiveront les cookies dans leur navigateur, ce qui signifie que le navigateur rejettera tous les cookies envoyés par un serveur dans une réponse. Les cookies désactivés posent bien sûr un problème aux sites qui doivent suivre les utilisateurs et les alternatives sont compliquées. Par exemple, une approche des "sessions sans cookie" consiste à placer l'identifiant de l'utilisateur dans l'URL. Les sessions sans cookie nécessitent que chaque URL qu'un site donne à un utilisateur contienne l'identifiant approprié, et les URL deviennent beaucoup plus volumineuses (c'est pourquoi cette technique est souvent appelée technique de "l'URL en gras").
Lorsqu'un site Web veut donner un cookie à un utilisateur, il utilise un Set-Cookie
en-tête dans une réponse HTTP.
HTTP / 1.1 200 OK Type de contenu: text / html; jeu de caractères = utf-8 Set-Cookie: fname = Scott $ lname = Allen; domain = .mywebsite.com; chemin = /…
Le cookie présenté dans cet exemple contient trois zones d’information. Les trois zones sont délimitées par des points-virgules (;). Premièrement, il existe une ou plusieurs paires nom-valeur. Ces paires nom-valeur sont délimitées par un signe dollar ($) et ressemblent beaucoup à la façon dont les paramètres de requête sont formatés en une URL. Dans l'exemple de cookie, le serveur souhaitait stocker le prénom et le nom de l'utilisateur dans le cookie. Les deuxième et troisième zones sont respectivement le domaine et le chemin. Nous reviendrons plus tard pour parler du domaine et du chemin..
Un site Web peut mettre toutes les informations qu'il souhaite dans un cookie, bien que sa taille soit limitée à 4 Ko. Cependant, de nombreux sites Web n'indiquent qu'un identifiant unique pour un utilisateur, par exemple un GUID. Un serveur ne peut jamais faire confiance à quoi que ce soit stocké sur le client s'il n'est pas sécurisé de manière cryptographique. Oui, il est possible de stocker des données cryptées dans un cookie, mais il est généralement plus facile de stocker un identifiant.
HTTP / 1.1 200 OK Set-Cookie: GUID = 00a48b7f6a4946a8adf593373e53347c; domaine = .msn.com; chemin = /
En supposant que le navigateur est configuré pour accepter les cookies, le navigateur envoie le cookie au serveur lors de chaque requête HTTP ultérieure..
GET… HTTP / 1.1 Cookie: GUID = 00a48b7f6a4946a8adf593373e53347c;…
Lorsque l'ID arrive, le logiciel serveur peut rapidement rechercher les données utilisateur associées à partir d'une structure de données en mémoire, d'une base de données ou d'un cache distribué. Vous pouvez configurer la plupart des infrastructures d'application Web pour manipuler les cookies et rechercher automatiquement l'état de la session. Par exemple, dans ASP.NET, le Session
object expose une API simple pour lire et écrire l'état de session d'un utilisateur. En tant que développeurs, nous n’avons jamais à nous soucier d’envoyer une Set-Cookie
en-tête ou en lisant les cookies entrants pour trouver l’état de session associé. En coulisse, ASP.NET va gérer le cookie de session.
Session ["firstName"] = "Scott"; // écriture de l'état de la session… var lastName = Session ["lastName"]; // lecture de l'état de la session
Encore une fois, il convient de souligner que le Prénom
et nom de famille
les données stockées dans l'objet de session sont ne pas entrer dans le cookie. Le cookie contient uniquement un identifiant de session. Les valeurs associées à l'identifiant de session sont sécurisées sur le serveur. Par défaut, les données de session entrent dans une structure de données en mémoire et restent actives pendant 20 minutes. Lorsqu'un cookie de session arrive dans une demande, ASP.NET associe les données de session correctes au Session
objet après avoir trouvé les données de l'utilisateur à l'aide de l'identifiant stocké dans le cookie. S'il n'y a pas de cookie entrant avec un ID de session, ASP.NET en créera un avec un Set-Cookie
entête.
Un problème de sécurité lié aux identificateurs de session est la manière dont ils peuvent ouvrir la possibilité à une personne de détourner la session d'un autre utilisateur. Par exemple, si j’utilise un outil tel que Fiddler pour suivre le trafic HTTP, il se peut que je voie un Set-Cookie
en-tête proviennent d'un serveur avec SessionID = 12
à l'intérieur. Je devine peut-être qu'un autre utilisateur a déjà un ID de session
sur 11, et créez une requête HTTP avec cet ID uniquement pour voir si je peux voler ou afficher le code HTML destiné à un autre utilisateur. Pour lutter contre ce problème, la plupart des applications Web utiliseront de grands nombres aléatoires comme identificateurs (ASP.NET utilise une résolution aléatoire de 120 bits). Un identifiant de session ASP.NET ressemble à ce qui suit, ce qui rend plus difficile de deviner à quoi ressemblerait l'ID de session d'une autre personne..
Set-Cookie: ASP.NET_SessionId = en5yl2yopwkdamv2ur5c3z45; chemin = /; HttpOnly
Un autre problème de sécurité lié aux cookies est leur vulnérabilité à une attaque par script intersite (XSS). Lors d'une attaque XSS, un utilisateur malveillant injecte du code JavaScript malveillant dans le site Web d'une autre personne. Si l'autre site envoie le script malveillant à ses utilisateurs, ce dernier peut modifier, inspecter et dérober des informations de cookie (ce qui peut entraîner un détournement de session ou pire)..
Pour lutter contre cette vulnérabilité, Microsoft a introduit le HttpOnly
drapeau (vu dans le dernier Set-Cookie
Exemple). le HttpOnly
flag indique à l'agent utilisateur de ne pas autoriser le code de script à accéder au cookie. Le cookie existe pour "HTTP uniquement" -i.e. voyager dans l'en-tête de chaque message de requête HTTP. Les navigateurs qui implémentent HttpOnly
n'autorisera pas JavaScript à lire ou à écrire le cookie sur le client.
Les cookies que nous avons vus jusqu'à présent sont cookies de session. Les cookies de session existent pour une session utilisateur unique et sont détruits lorsque l'utilisateur ferme le navigateur.. Cookies persistants peut survivre à une seule session de navigation et un agent utilisateur stockera les cookies sur le disque. Vous pouvez éteindre un ordinateur et revenir une semaine plus tard, accéder à votre site Web préféré, et un cookie persistant sera toujours là pour la première demande..
La seule différence entre les deux est qu’un cookie persistant nécessite un Expire
valeur.
Set-Cookie: nom = valeur; expire = lundi, 09-juillet-2012 21:12:00 GMT
Un cookie de session peut explicitement ajouter un Jeter
attribuer à un cookie, mais sans Expire
l’utilisateur doit supprimer le cookie dans tous les cas..
Jusqu'à présent, nous avons dit qu'une fois qu'un cookie est défini par un site Web, le cookie sera redirigé vers le site Web à chaque nouvelle demande (en supposant que le cookie ne soit pas expiré). Cependant, tous les cookies ne se rendent pas sur tous les sites. Les seuls cookies qu'un agent utilisateur doit envoyer sur un site sont les cookies donnés à l'agent utilisateur par le même site. Il n’a pas de sens que les cookies de amazon.com soient dans une requête HTTP adressée à google.com. Ce type de comportement ne pouvait que susciter des préoccupations supplémentaires en matière de sécurité et de confidentialité. Si vous définissez un cookie dans une réponse à une demande adressée à www.server.com, le cookie résultant sera acheminé uniquement dans les demandes adressées à www.server.com..
Une application Web peut également modifier la portée d'un cookie pour le limiter à un hôte ou à un domaine spécifique, voire à un chemin de ressource spécifique. L’application Web contrôle l’étendue à l’aide de la touche domaine
et chemin
les attributs.
HTTP / 1.1 200 OK Set-Cookie: nom = valeur; domaine = .server.com; path = / stuff…
le domaine
attribut permet à un cookie de s'étendre sur des sous-domaines. En d'autres termes, si vous définissez un cookie à partir de www.server.com, l'agent utilisateur n'enverra le cookie qu'à www.server.com. Le domaine de l'exemple précédent permet également au cookie de se rendre vers n'importe quelle URL du domaine server.com, y compris images.server.com, help.server.com et tout simplement server.com. Vous ne pouvez pas utiliser l'attribut de domaine pour étendre des domaines. Il n'est donc pas légal de définir le domaine sur .microsoft.com dans une réponse à .server.com. L'agent utilisateur doit rejeter le cookie..
le chemin
attribut peut restreindre un cookie à un chemin de ressource spécifique. Dans l'exemple précédent, le cookie ne se rendra sur un site server.com que lorsque l'URL de la demande pointe vers /des trucs
, ou un endroit en dessous /des trucs
, comme / stuff / images
. Les paramètres de chemin peuvent aider à organiser les cookies lorsque plusieurs équipes créent des applications Web selon des chemins différents..
Les cookies permettent aux sites Web de stocker des informations dans le client. Ces informations seront ensuite renvoyées sur les sites lors de demandes ultérieures. Les avantages pour le développement Web sont énormes, car les cookies nous permettent de savoir quelle requête appartient à quel utilisateur. Mais, les cookies ont des problèmes que nous avons déjà évoqués.
Comme nous l'avons mentionné précédemment, les cookies sont vulnérables aux attaques XSS et reçoivent également une mauvaise publicité lorsque des sites (en particulier des sites de publicité) utilisent cookies tiers suivre les utilisateurs sur Internet. Les cookies tiers sont des cookies qui sont définis à partir d'un domaine différent de celui de la barre d'adresse du navigateur. Les cookies tiers offrent cette possibilité car de nombreux sites Web, lors du renvoi d’une ressource de page au client, incluent des liens vers des scripts ou des images à partir d’autres URL. Les demandes qui accèdent aux autres URL permettent aux autres sites de définir des cookies..
Par exemple, la page d’accueil sur server.com peut inclure un >