Comprendre le mécanisme
HTTP transporte des requêtes indépendantes ; une session ajoute un état serveur associé à un identifiant. Un cookie reçu reste une donnée du client, même si son nom semble interne. Secure limite l’envoi du cookie à HTTPS et HttpOnly son accès direct par JavaScript ; aucun de ces attributs ne décide des autorisations métier. Après une authentification ou une élévation de privilèges, prévoyez une rotation de l’identifiant avec gestion des requêtes concurrentes.
Raisonner et vérifier
Les superglobales contiennent des entrées non fiables. Validez taille, forme et droits avant toute opération. Pour un upload, contrôlez l’erreur de transfert, la taille réelle, le type détecté et le contenu attendu ; générez un nom serveur et empêchez l’exécution dans le répertoire de stockage. Réduisez la durée du verrou de session en fermant la session dès que les modifications utiles sont enregistrées.
Une session est un état accepté par le serveur
Le cookie de session transporte souvent une référence opaque, pas une preuve autonome de tous les droits. Le serveur résout cette référence et applique ses règles de validité, d’expiration et d’activation du compte. Définissez les limites de durée et ce qui arrive après une désactivation. Une date côté navigateur ne suffit pas : un détenteur d’une ancienne copie peut encore présenter la même référence à un autre client.
Understand this common mistake
Le cookie client décide seul de tout droit serveur.
Le serveur conserve la politique d’identité et d’accès.
Changer de contexte d’identité
Le passage d’une session anonyme à une session authentifiée change les capacités associées à son identifiant. Une politique de rotation doit empêcher qu’un identifiant choisi ou conservé par un tiers devienne une capacité privilégiée. Vérifiez l’ancien et le nouvel identifiant après la transition. Le succès du formulaire de connexion ne prouve pas, à lui seul, que l’ancienne référence a perdu tous les usages interdits.
Understand this common mistake
Un identifiant anonyme doit toujours rester utilisable après login.
La fixation doit être traitée selon la transition.
Une lecture ne doit pas demander une annulation
GET sert à demander une représentation selon une sémantique sûre. Les navigateurs, outils de préchargement et robots peuvent effectuer cette lecture sans clic volontaire d’annulation. Placez les mutations derrière une méthode et un contrat adaptés, puis vérifiez identité, permission et état métier. Changer seulement le texte d’un lien ne corrige pas une route GET dont le serveur continue à supprimer une ressource.
Understand this common mistake
GET est idéal pour supprimer une commande.
Les lectures peuvent être déclenchées automatiquement.
La défense CSRF précède l’effet
Un navigateur peut envoyer automatiquement son cookie lors d’un parcours déclenché ailleurs. Le serveur doit donc distinguer une demande conforme à son contexte de formulaire d’une demande forgée. Vérifiez le jeton CSRF et les autres contrôles requis avant l’écriture. Les tests doivent fournir valeur correcte, valeur absente et valeur incorrecte, puis vérifier le statut et l’absence de mutation dans les deux derniers cas.
Understand this common mistake
Un cookie présent suffit à prouver un clic volontaire.
Le navigateur peut envoyer des credentials automatiquement.
Portée précise de HttpOnly
HttpOnly limite la lecture directe du cookie par les API JavaScript habituelles. Cette propriété réduit une voie de vol, mais ne neutralise pas toutes les conséquences d’un script hostile exécuté dans l’origine. Le script peut encore demander des actions au serveur. Conservez donc prévention XSS, contrôles d’autorisation et politique de session ; ne traduisez pas un attribut de cookie en garantie générale de sécurité du navigateur.
Understand this common mistake
HttpOnly supprime toute conséquence d’une XSS.
Le script peut encore agir dans l’origine compromise.
Transport sécurisé et capacité sensible
Secure demande un envoi du cookie dans les conditions de transport sécurisé prévues par le navigateur. Le contenu opaque reste une capacité sensible s’il peut être rejoué. L’attribut ne dit rien sur le propriétaire d’une réservation ni sur la validité actuelle du compte. Vérifiez la réponse réellement déployée et le contexte proxy : une mauvaise perception du schéma peut influencer les cookies et URL générés.
Understand this common mistake
Secure autorise tout utilisateur comme administrateur.
L’attribut ne décide pas des droits métier.
Construire la réponse et servir les fichiers
Les en-têtes appartiennent au message HTTP et doivent être construits avant l’émission incompatible du corps selon le contexte PHP. Utilisez les API du framework pour statuts, cookies et téléchargements. Pour un upload destiné au public, choisissez un nom généré côté serveur et un espace sans exécution de code. Le nom fourni par le client ne doit pas devenir librement un chemin de stockage ou une règle de présentation.
Understand this common mistake
Une sortie déjà envoyée ne peut jamais gêner la gestion des headers.
Le cycle d’émission des champs doit être respecté.
Statuts et chemins d’erreur
Un statut donne une information protocolaire utile aux clients et à la supervision. Ne transformez pas toute panne en réponse 200. Définissez un schéma d’erreur public et une corrélation privée sans exposer les détails internes. Un refus de droit, une entrée invalide et une dépendance indisponible n’impliquent pas toujours la même reprise. Testez le corps autant que le statut, notamment sur les erreurs qui contournent le chemin nominal.
Understand this common mistake
Toute erreur doit devenir 200 pour les clients.
Les clients et outils utilisent aussi le statut.
Session, concurrence et cache
Une session peut introduire une contention si son mécanisme de stockage conserve un verrou pendant un traitement long. Une fois la lecture et les écritures de session utiles terminées, fermer tôt la session peut réduire l’attente des requêtes parallèles ; vérifiez le contrat du handler utilisé. Séparez cette question de celle du cache : une réponse personnalisée ne doit pas être distribuée à un autre compte par une clé trop générale.
Understand this common mistake
Toutes les sessions peuvent partager la même réponse privée.
La frontière inter-utilisateurs doit être préservée.
Le logout n’est pas une suppression universelle
Effacer un cookie sur un navigateur retire cette copie locale. Cela ne prouve pas le retrait des autres copies ni de tous les états de validation. Définissez ce que le logout doit invalider côté serveur et mesurez sa propagation si plusieurs instances participent. Un test avec deux clients permet de vérifier la distinction : fermer le premier ne suffit pas à démontrer que le second ne peut plus utiliser l’ancienne capacité.
Understand this common mistake
Fermer un navigateur invalide tous les tokens ailleurs.
Le retrait serveur doit avoir un mécanisme explicite.
Atelier guidé : lire, expliquer et vérifier le code
<?php
declare(strict_types=1);
$expected = 'lab-A';
$provided = 'lab-B';
$writes = 0;
if (hash_equals($expected, $provided)) { ++$writes; }
echo $writes; Le petit programme de validation CSRF compare deux chaînes distinctes. La branche contenant l’incrément n’est pas exécutée et writes reste égal à zéro. Le point important est l’ordre : aucune écriture ne précède la comparaison. Remplacer la réponse finale par un statut de refus après un incrément ne donnerait pas la même propriété, même si le navigateur affichait une erreur.
Déplacez volontairement l’effet avant la garde dans une copie de laboratoire et écrivez un test qui observe le compteur. Ce test doit échouer sur la version incorrecte. Ajoutez ensuite un contrôle d’autorisation indépendant : un token valide ne doit pas permettre à un acteur d’annuler une réservation d’un autre compte. Vous aurez alors deux preuves séparées pour deux frontières différentes.
Worked example
<?php
session_start([
'use_strict_mode' => true,
'cookie_secure' => true,
'cookie_httponly' => true,
'cookie_samesite' => 'Lax',
]);
$memberId = $_SESSION['member_id'] ?? null;
session_write_close();Ce fragment configure des protections de transport et libère rapidement le verrou. L’existence de memberId ne remplace pas le contrôle d’accès à la réservation demandée.
Practical exercise
Décrivez les contrôles d’un endpoint qui reçoit une image de réservation. Incluez un test de fichier PHP renommé en JPEG.
View a suggested solution
Vérifiez le fichier reçu et son type réel, limitez les dimensions et octets, attribuez un nom non fourni par le client et stockez dans un espace sans exécution. Refusez le fichier trompeur avant publication.
Verification checklist
- Ne jamais faire confiance au MIME déclaré seul.
- Gérer fixation et renouvellement de session.
- Autoriser chaque ressource côté serveur.
Knowledge check
Related lesson: HTTP, formulaires, sessions et uploads ↗Module validation
101 questions, local practice target of 75%. Suggested duration of 150 minutes, with no enforced deadline. Questions and choices are shuffled; corrections appear after submission. The quick lesson check and the final course exam remain separate exercises.
Start or resume the 101 questions →This records your own progress and does not certify mastery. Complete the exercise before moving on.
