Formulaire de connexion : mot de passe dans l'URL
Le site de réservation de salles d'un lycée comporte un formulaire de connexion :
<form method='get' action='/login'>
<input name='identifiant'>
<input type='password' name='motdepasse'>
<button>Se connecter</button>
</form>
Les journaux du serveur affichent des requêtes GET /login?identifiant=marie&motdepasse=Secret123. Le JavaScript de la page contient if (mdp.length > 8) { afficherErreur(); }, ce qui refuse le mot de passe motdepasse de neuf caractères. Après connexion, la page de réservation appelle /reserver sans envoyer de jeton, et le serveur ne vérifie que la présence d'un cookie connecte=oui, que l'on peut fabriquer à la main. Le proviseur demande un audit avant la rentrée. Aucun test d'intrusion n'a encore été réalisé.
1. Expliquer pourquoi `method='get'` est un mauvais choix pour ce formulaire, en citant au moins trois conséquences concrètes. Proposer une correction côté HTML et côté serveur.
Read the worked answer
GET place les paramètres dans l'URL. Ici le mot de passe se retrouve dans l'historique du navigateur, dans les journaux du serveur et du proxy, dans l'en-tête Referer si la page charge une ressource externe, et dans les caches. Il est aussi visible à l'écran et copiable. Il faut utiliser method='post' pour le formulaire, servir la page en HTTPS, ne jamais journaliser le corps de la requête de connexion, et stocker le mot de passe sous forme de hash côté serveur. POST seul ne chiffre rien : sans HTTPS, le mot de passe circule en clair. Côté serveur, il faut aussi limiter les tentatives et ne pas renvoyer le mot de passe dans l'URL de redirection.
2. Corriger la condition JavaScript et expliquer pourquoi la validation côté client ne peut pas garantir la sécurité. Où doit être vérifiée la longueur minimale ?
Read the worked answer
La condition est inversée : mdp.length > 8 refuse les mots de passe de plus de 8 caractères, donc accepte les plus courts. Pour imposer au moins 8 caractères, il faut if (mdp.length < 8). La validation côté client améliore l'expérience mais ne garantit rien : on peut désactiver JavaScript, modifier la page ou envoyer une requête forgée avec curl. La longueur minimale, le format et l'existence de l'identifiant doivent être vérifiés côté serveur. Le client ne doit pas non plus décider seul du rôle ou des droits.
3. Décrire la faille d'autorisation sur `/reserver` et la corriger. Pourquoi un cookie `connecte=oui` n'est-il pas une preuve d'authentification ?
Read the worked answer
Le cookie connecte=oui est une simple chaîne envoyée par le navigateur. N'importe qui peut le créer avec les outils de développement ou une requête forgée. Le serveur ne doit pas faire confiance à une valeur booléenne non signée. Il doit utiliser un identifiant de session aléatoire et imprévisible, stocké côté serveur, transmis dans un cookie HttpOnly, Secure et SameSite, et vérifier à chaque requête que la session existe, qu'elle n'a pas expiré et que l'utilisateur a le droit de réserver cette salle. Pour /reserver, il faut aussi un jeton anti-CSRF et une vérification du rôle. Enfin, la réservation doit être validée côté serveur (salle existante, créneau libre), pas seulement par le JavaScript.