Comprendre le mécanisme
Une donnée traverse plusieurs contextes : SQL, HTML, chemins, logs ou commandes. Un encodage adapté à l’un ne protège pas les autres. Pour HTML, l’échappement de sortie conserve les données comme texte ; pour SQL, les valeurs sont liées ; pour une commande, réduisez d’abord le besoin d’exécution et évitez la construction libre d’une ligne shell. L’autorisation répond à la question « cet acteur peut-il agir sur cette ressource ? », distincte de l’authentification.
Raisonner et vérifier
Hachez les mots de passe avec une API dédiée et vérifiez-les avec password_verify. Un token CSRF protège une action contre des déclenchements intersites indésirables, pas contre toutes les attaques. Évitez de désérialiser des objets issus d’une source non fiable. Les erreurs publiques doivent être utiles sans divulguer secrets, traces SQL ou tokens ; les journaux gardent des événements minimisés et un identifiant de corrélation.
Vérifier un mot de passe selon son format
password_hash crée un format adapté à la vérification d’un secret humain, avec ses paramètres et son sel. password_verify vérifie ensuite une valeur présentée contre ce format. Un hash rapide comme MD5 ne fournit pas un coût approprié de résistance aux essais hors ligne. Après succès, une politique peut demander un rehash ; un échec ne doit jamais remplacer la preuve stockée par la mauvaise valeur reçue.
Erreur fréquente à comprendre
MD5 direct fournit un coût adaptatif approprié.
Une fonction dédiée doit ralentir et paramétrer les essais.
La sortie détermine le contrôle pertinent
Une chaîne peut être destinée à du texte HTML, une URL, du JavaScript ou une valeur SQL. Ces contextes ne partagent pas une protection universelle. htmlspecialchars ne transforme pas une concaténation SQL en requête paramétrée. Pour un libellé navigateur, une insertion textuelle peut éviter l’interprétation HTML. Commencez chaque revue par le point d’utilisation de la donnée, puis choisissez le contrôle qui correspond à ce contexte précis.
Erreur fréquente à comprendre
Un échappement HTML sécurise tout SQL.
Les contextes exigent des contrôles différents.
L’objet fait partie de l’autorisation
Un utilisateur connecté n’obtient pas automatiquement l’accès à une réservation dont il connaît l’identifiant. Les UUID et paramètres SQL protègent d’autres propriétés que l’isolation métier. Résolvez la ressource dans le bon tenant et vérifiez l’opération demandée. Le test doit essayer deux acteurs avec le même identifiant et observer le refus sans effet du second ; une interface qui masque le lien ne bloque pas un client direct.
Erreur fréquente à comprendre
Une identité connectée peut lire toute ligne par son ID.
L’authentification ne donne pas tous les droits.
Les références reçues ne donnent pas accès au système
Un chemin fourni par le client ne doit pas sélectionner librement un fichier serveur. Préférez un identifiant métier résolu dans un stockage maîtrisé, avec autorisation avant lecture. La même prudence vaut pour une préférence sérialisée : un texte reçu ne doit pas reconstruire arbitrairement des objets et leurs comportements. Dans une nouvelle API, un format de données simple avec validation explicite limite les capacités accordées au parsing.
Erreur fréquente à comprendre
Un chemin client absolu constitue une permission de lecture.
La sélection du fichier doit être contrôlée.
Un token décodé n’est pas une identité validée
Le payload d’un JWT peut être lisible sans que sa signature soit correcte. Avant d’utiliser sub ou role, appliquez le contrat du profil : preuve cryptographique, clé et algorithme admis, issuer, audience, types et règles temporelles nécessaires. Ces contrôles établissent une identité utilisable dans ce contexte. L’autorisation sur la ressource vient ensuite ; une signature valide ne donne pas une permission universelle.
Erreur fréquente à comprendre
Un payload décodé suffit à accorder admin.
Le parsing n’établit pas l’authenticité.
Un upload consomme plusieurs budgets
La limite du formulaire ne contrôle pas à elle seule le proxy, PHP, le disque ou la décompression d’une archive. Définissez taille reçue, nombre d’entrées, volume extrait et temps de traitement. Vérifiez le contenu selon l’usage plutôt que le seul suffixe client. Le stockage et la restitution doivent aussi limiter exécution, chemins et accès inter-comptes. Un fichier accepté n’est pas automatiquement sûr dans tout contexte de distribution.
Erreur fréquente à comprendre
Un type MIME client garantit un fichier sain et petit.
La déclaration ne vérifie ni contenu ni coût.
Distinguer CSRF et XSS
Le CSRF profite notamment de l’envoi automatique d’une identité par le navigateur ; une XSS exécute un script dans un contexte compromis. Un token CSRF ne neutralise pas ce script, et HttpOnly ne supprime pas toutes ses actions. Les protections doivent donc être combinées selon leurs propriétés. Testez une mutation avec token absent, puis un rendu de donnée hostile ; ce sont deux frontières et deux preuves différentes.
Erreur fréquente à comprendre
Un token CSRF neutralise toute injection de script.
Une XSS peut compromettre le contexte de confiance.
Maîtriser les sorties HTTP serveur
Une URL HTTPS reçue d’un client n’est pas forcément une destination autorisée. Un serveur peut disposer d’accès internes que l’appelant ne devrait pas piloter. Résolvez des partenaires identifiés dans un périmètre maîtrisé et vérifiez redirections, résolution réseau, taille et durée. Une URL initiale correcte ne suffit pas si un saut suivant change le destinataire. Les tests doivent employer un laboratoire et des dépendances simulées.
Erreur fréquente à comprendre
Toute URL HTTPS reçue est une destination sûre.
Le canal ne rend pas la destination autorisée.
Limiter l’abus sans inventer des droits
Un quota protège une ressource ou un coût selon une fenêtre et des dimensions de comptage. Il ne vérifie pas les permissions sur une réservation. Inversement, un acteur autorisé peut encore épuiser une opération coûteuse. Définissez ces deux décisions séparément et placez la limitation avant l’effet qu’elle veut borner. Un compteur seulement local ne démontre pas une limite globale si plusieurs instances traitent la charge.
Erreur fréquente à comprendre
Un quota disponible donne des droits métier.
Le budget et l’autorisation sont distincts.
Limiter les conséquences d’un diagnostic
Les logs d’authentification ne doivent pas devenir un stock de tokens, cookies et mots de passe. Des catégories de refus, une version et une corrélation peuvent suffire à l’investigation. Pour un outil CLI, la protection des arguments a aussi plusieurs niveaux : escapeshellarg traite une frontière du shell, mais une valeur commençant par un tiret peut encore devenir une option pour le programme lancé. Préférez une API adaptée et une grammaire d’entrée limitée.
Erreur fréquente à comprendre
Un log interne peut exposer tous les bearer tokens sans risque.
Une fuite de diagnostic peut créer une capacité d’usurpation.
Atelier guidé : lire, expliquer et vérifier le code
<?php
declare(strict_types=1);
$body = 'document de laboratoire';
$reference = hash('sha256', $body);
echo hash_equals($reference, hash('sha256', $body)) ? 'same' : 'different'; Le programme calcule deux fois une empreinte SHA-256 sur les mêmes octets puis compare les chaînes attendues. La sortie same établit cette égalité dans le petit scénario. Elle ne prouve pas l’auteur du document : aucune référence authentifiée ni clé de signature n’apparaît. Un adversaire capable de remplacer le fichier et la référence publique peut recalculer les deux.
Conservez une référence séparée dans le laboratoire et modifiez un octet du contenu pour observer le refus. Remplacez ensuite les deux valeurs ensemble et notez la limite de cette preuve d’intégrité. Pour une authenticité partagée, étudiez un MAC avec une clé protégée ; pour un droit de lecture, ajoutez une décision d’autorisation. Ces propriétés nécessitent des contrôles distincts même si elles utilisent toutes des chaînes en PHP.
Argument shell délimité et option du programme
Escapeshellarg traite une frontière du shell : il vise à conserver une valeur comme un argument. Le programme lancé interprète ensuite cet argument selon ses propres règles. Un nom commençant par un tiret peut donc être lu comme une option même s’il n’a pas créé un second argument shell.
Préférez une API de bibliothèque lorsqu’elle couvre le besoin. Sinon, évitez le shell avec une API de processus à arguments séparés, validez l’opérande et utilisez le séparateur -- seulement si l’outil le documente. Vérifiez aussi chemin résolu et répertoire autorisé : aucun mécanisme de quoting n’établit un droit sur un fichier.
Dans un laboratoire, remplacez l’outil par un programme qui affiche ses arguments factices, puis vérifiez la commande cible sans effets sensibles. Testez tiret initial, espaces et nom hors périmètre. La preuve recherchée est une interprétation conforme de l’opérande par le programme final, pas simplement une chaîne qui semble correctement entourée de guillemets.
Points de vigilance : TLS protège le transport, mais ne définit pas la grammaire des arguments du programme. L’échappement vise justement la frontière du shell ; l’autre problème est l’interprétation par l’outil. Le scénario ne fait intervenir aucune requête SQL. Un argument correctement délimité peut rester une option dangereuse. Préférer une API, sinon éviter le shell et contrôler les arguments.
Documentation de référence ↗UUID et requête préparée : deux protections sans preuve de tenant
Un UUID peut réduire la facilité de deviner une référence. Une requête préparée protège la séparation entre structure SQL et valeurs. Aucun de ces mécanismes ne prouve que la facture trouvée appartient à l’acteur ou à son tenant.
La portée doit venir du contexte authentifié et autorisé côté serveur. Chargez la facture avec les critères de périmètre nécessaires ou appliquez une décision d’objet avant de transmettre son contenu. Un tenantId librement reçu dans la query ne remplace pas cette source de confiance.
Créez deux tenants et une facture de chacun, puis présentez l’UUID valide du premier avec la session du second. Vérifiez absence de corps confidentiel et absence d’effet. Gardez aussi le cas du propriétaire et celui de la ressource absente. Cette matrice distingue l’isolation réelle d’un endpoint qui paraît protégé seulement parce que ses identifiants sont longs ou que son SQL utilise des placeholders.
Points de vigilance : Un identifiant opaque ne remplace pas le contrôle du droit de lecture. Limiter le volume ne rend pas autorisée une seule lecture interdite. La portée doit venir d’un contexte authentifié et autorisé, pas d’un tenantId librement fourni. Une référence peut être connue par de nombreux canaux même si l’interface la masque.
Documentation de référence ↗Exemple commenté
<?php
declare(strict_types=1);
$name = '<script>alert(1)</script>';
echo htmlspecialchars($name, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');Le navigateur reçoit une représentation textuelle des caractères spéciaux dans ce contexte HTML. La même fonction ne sécurise pas une requête SQL concaténée.
Exercice de mise en pratique
Établissez une matrice de tests pour consulter ou annuler une réservation d’un autre utilisateur.
Voir une proposition de correction
Créez deux acteurs et deux ressources. Vérifiez l’autorisation pour lecture et mutation, y compris avec un identifiant deviné. Ajoutez tests CSRF et sorties contenant des caractères HTML.
Points de vérification
- Identifier le contexte exact.
- Ne pas confondre authentification et autorisation.
- Exclure les secrets des logs.
Contrôle de connaissances
Cours associé : Sécurité aux frontières de confiance ↗Validation du module
101 questions, objectif pédagogique de 75 %. Durée conseillée de 150 minutes, sans limite imposée. Les questions et les choix sont mélangés ; le corrigé apparaît après validation. Le contrôle rapide de la leçon et l’examen final du cours restent des exercices distincts.
Commencer ou reprendre les 101 questions →Cette marque suit votre propre avancement ; elle ne certifie pas la maîtrise du sujet. Effectuez l’exercice avant de passer à la suite.
