4.7.6 Tester les fonctionnalités de déconnexion (OTG-SESS-006)

Sommaire
La fin d'une session est une partie importante du cycle de vie d'une session. Réduire au minimum la durée de vie des jetons de session réduit les chances de réussite d'une attaque de détournement de session. Cela peut être vu comme un contrôle visant à prévenir les attaques Cross Site Scripting et Cross Site Request Forgery. De telles attaques sont en effet connues pour reposer sur l'existence d'une session authentifiée. Ne pas avoir de mécanisme de fin de session sécurisé ne fait qu'accroître la surface d'attaque.

Une fin de session sécurisée nécessite au moins les éléments suivants :


 * Existence d'une interface utilisateur permettant explicitement de se déconnecter.
 * Fin de session automatique après un certain temps d'inactivité (session timeout).
 * Désactivation effective de la session côté serveur.

De multiples problèmes peuvent empêcher une fin efficace d'une session. Dans une application web idéalement sécurisée, un utilisateur devrait pouvoir terminer sa session à n'importe quel moment, via l'interface utilisateur. Chaque page devrait inclure un bouton de déconnexion, directement visible. Des fonctions de déconnexion ambiguës ou manquant de clarté peuvent entraîner un manque de confiance de l'utilisateur dans leur efficacité.

Une autre erreur commune dans les fins de session est renouveler jeton de session côté client alors que l'état côté serveur demeure actif et peut être réutilisé en redonnant son ancienne valeur au cookie de session. Parfois, aucune action n'est effectuée à part l'envoi d'un message de confirmation à l'utilisateur. Cela doit être évité.

Certains environnements d'application web reposent seulement sur le cookie de session pour identifier un utilisateur connecté. L'identifiant d'utilisateur est inclus dans la valeur (chiffrée) du cookie. Le serveur d'application ne fait aucun suivi de la session côté serveur. Lors de la déconnexion, le cookie est supprimé du navigateur. Cependant, comme l'application ne fait aucun suivi, elle ne sait pas si la session est déconnectée ou pas. Ainsi, en réutilisant le cookie il est possible d'accéder à la session authentifiée. La fonctionnalité Forms Authentication (authentification par formulaire) d'ASP.NET en est un exemple bien connu.

Il arrive que les utilisateurs de navigateurs web ne se soucient pas qu'une application reste ouverte ou pas et ferment simplement le navigateur ou un onglet. Une application web devrait prendre en compte ce comportement et terminer la session automatiquement côté serveur après un délai déterminé.

L'utilisation d'un système d'authentification unique (single sign-on SSO) à la place d'une authentification par l'application entraîne souvent l'existence de plusieurs sessions qui doivent être terminées séparément. Par exemple, la fin d'une session applicative ne termine pas la session dans le système SSO. En naviguant à nouveau sur le portail SSO, l'utilisateur a la possibilité de se reconnecter sur l'application d'où il s'était déconnecté précédemment. D'autre part, la fonction de déconnexion du système SSO n'entraîne pas forcément la fin des sessions sur les applications connectées.

Comment tester
Tester l'interface utilisateur de déconnexion : Vérifier l'apparence et la visibilité de la fonctionnalité de déconnexion dans l'interface utilisateur. Pour cela, il faut regarder chaque page avec le point de vue d'un utilisateur qui a l'intention de se déconnecter de l'application web.

Résultat attendu : Une bonne interface de déconnexion a certaines propriétés :
 * Un bouton de déconnexion doit être présent sur toutes les pages de l'application.
 * Le bouton de déconnexion doit être rapidement reconnaissable par l'utilisateur voulant se déconnecter de l'application web.
 * Après le chargement de la page, le bouton de déconnexion doit être visible sans avoir à faire défiler le contenu.
 * Idéalement, le bouton de déconnexion sera placé dans une zone fixe de la page, qui ne doit pas être modifiée par le défilement du contenu.

Tester les fins de session côté serveur : D'abord, stocker toutes les valeurs de cookies servant à identifier une session. Appeler la fonction de déconnexion et observer le comportement de l'application, et, en particulier, les cookies de session. Essayer de naviguer sur une page qui n'est visible qu'avec une session authentifiée, par exemple avec le bouton retour du navigateur. Si c'est la version en cache de la page qui est affichée, utiliser le bouton de rafraîchissement pour recharger la page depuis le serveur. Si la fonction de déconnexion renouvelle les cookies de session, restaurer les anciennes valeurs des cookies de session et recharger une page d'une zone authentifiée de l'application. Si ces tests ne montrent pas de vulnérabilités sur une page particulière, il faut tester au moins quelques autres pages considérées comme critiques, pour s'assurer que la fin de session s'effectue correctement dans ces parties de l'application.

Résultat attendu : Aucune donnée limitée aux utilisateurs authentifiés ne devrait être visible sur les pages examinées pendant les tests. Idéalement, lorsque l'on accède à une partie authentifiée après la fin de la session, l'application doit rediriger vers une partie publique ou une page de connexion. Cela ne devrait pas être nécessaire à la sécurisation de l'application, mais changer les valeurs des cookies de session après déconnexion est généralement considéré comme une bonne pratique.

Tester les délais d'expiration de session : Essayer de déterminer le délai d'expiration d'une session en accédant à la zone authentifiée de l'application web à des intervalles de temps croissants. La durée de vie de la session correspond approximativement au délai constaté au moment de la déconnexion.

Résultat attendu: Les mêmes résultats que pour les tests de fin de session côté serveur, décrits plus haut, sont attendus après une déconnexion due à une inactivité.

Le délai d'expiration d'une session dépend de l'usage de l'application et doit être un compromis entre sécurité et facilité d'utilisation. Dans une application bancaire, cela n'a pas de sens de garder une session inactive plus de 15 minutes. Par contre, une durée trop courte sur un wiki ou un forum risque d'importuner les utilisateurs qui saisissent des articles longs avec des demandes de reconnexion inutiles. Dans ce cas, une durée d'une heure ou plus peut être acceptable.

Tester les fins de session en environnement d'authentification unique SSO (single sign-off) : D'abord, se déconnecter de l'application. Vérifier ensuite si le portail central ou l'annuaire d'application permet à l'utilisateur de se reconnecter à l'application sans authentification. Tester si l'application demande à l'utilisateur de s'authentifier lorsqu'il accéde à une URL d'entrée de l'application. Une fois connecté à l'application, il faut se déconnecter du système SSO, puis essayer d'accéder à des parties authentifiées de l'application.

Résultat attendu : Une déconnexion de l'application connectée à un système SSO ou une déconnexion du système SSO doit entraîner la fin de toutes les sessions. Une nouvelle authentification doit être demandée pour accéder à l'application après déconnexion du SSO et de l'application.

Outils

 * "Burp Suite - Repeater" - http://portswigger.net/burp/repeater.html

Références
Whitepapers
 * "La méthode FormsAuthentication.SignOut ne protège pas des attaques par rejeu de cookies dans les applications ASP.NET" - http://support.microsoft.com/default.aspx?scid=kb;en-us;900111
 * "Attaques par rejeu de cookies dans ASP.NET en utilisant les formulaires d'authentification" - https://www.vanstechelman.eu/content/cookie-replay-attacks-in-aspnet-when-using-forms-authentication