← PHP 8.4 — ingénierie et préparation Zend

Module 7 / 8 · 90 min

Sécurité aux frontières de confiance

Choisir la protection adaptée au contexte d’interprétation.

Lessons, exercises and questions in this path are in French. The interface follows the site language.

Your progress will appear here when JavaScript is active.

Progress and best score are stored only in this browser. No account is needed; clearing browser data removes them. Module times are estimates including exercises.

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.

Understand this common mistake

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.

Understand this common mistake

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.

Understand this common mistake

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.

Understand this common mistake

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.

Understand this common mistake

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.

Understand this common mistake

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.

Understand this common mistake

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.

Understand this common mistake

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.

Understand this common mistake

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.

Understand this common mistake

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.

Reference documentation ↗

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.

Reference documentation ↗

Worked example

<?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.

Practical exercise

Établissez une matrice de tests pour consulter ou annuler une réservation d’un autre utilisateur.

View a suggested solution

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.

Verification checklist

  • Identifier le contexte exact.
  • Ne pas confondre authentification et autorisation.
  • Exclure les secrets des logs.

Knowledge check

Related lesson: Sécurité aux frontières de confiance ↗
Quel contrôle compare un mot de passe à un hash password_hash ?

Reference documentation ↗

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 →