TP – Enregistrer les réservations en base
BTS SIO SISR 2e année – Bloc 1 – S09 – binôme
Note
But. Tu crées la base du portail, tu l'interroges, tu écris deux pages PHP (liste et ajout) avec des requêtes préparées, tu réalises une injection SQL sur une page volontairement vulnérable puis tu la corriges, et tu limites les droits du compte.
Durée : 2 h 50 (parties A à D), plus le bilan. Prérequis : cours S09 lu ; S07 et S08. Fichiers : schema.sql, connexion.php, injection-vulnerable.php.
Note
Comment ce TP fonctionne. Avant chaque manipulation, tu écris ce que tu anticipes (« J'anticipe »). Puis tu confrontes avec les éléments de réponse.
Binôme : ____________ / ____________
Contraintes
- Travail uniquement sur la machine virtuelle de laboratoire (Debian ou Ubuntu avec Apache, PHP, extension PDO MySQL et MariaDB). Le mot de passe du compte
portailest un identifiant de laboratoire. - La page vulnérable ne sert que pour la démonstration ; elle n'est jamais installée sur un serveur accessible de l'extérieur.
- Les associations, adresses et dates sont fictives.
Partie A – Créer et interroger la base (≈ 40 min)
- Charge le schéma :
sudo mariadb < schema.sql. - Crée un compte à droits limités :
CREATE USER 'portail'@'localhost' IDENTIFIED BY 'motdepasse-de-labo';
GRANT SELECT, INSERT ON portail.* TO 'portail'@'localhost';
FLUSH PRIVILEGES;
- Écris et exécute les requêtes suivantes :
| N° | Besoin | Ta requête |
|---|---|---|
| 1 | Les salles de 50 places ou plus, de la plus grande à la plus petite | |
| 2 | Le nombre de réservations par salle le 15 mars 2030 | |
| 3 | Le nombre de minutes réservées par salle (toutes dates) | |
| 4 | Le créneau 10 h–12 h de la salle 1 le 15 mars 2030 est-il libre ? |
J'anticipe. Que renvoie la requête 4 ? Et pour 11 h–12 h ? ______________________
Éléments de réponse
SELECT nom, capacite FROM salles WHERE capacite >= 50 ORDER BY capacite DESC;→ salle des fêtes (200), gymnase (120), salle d'exposition (60).SELECT s.nom, COUNT(*) FROM reservations r JOIN salles s ON s.id = r.salle_id WHERE r.jour = '2030-03-15' GROUP BY s.nom;→ salle des fêtes 2, salle du conseil 1.SELECT s.nom, SUM(TIME_TO_SEC(r.fin) - TIME_TO_SEC(r.debut)) / 60 FROM reservations r JOIN salles s ON s.id = r.salle_id GROUP BY s.nom;→ gymnase 120, salle des fêtes 210, salle du conseil 120.SELECT COUNT(*) FROM reservations WHERE salle_id = 1 AND jour = '2030-03-15' AND debut < '12:00' AND fin > '10:00';→ 1 (la réservation 9 h–11 h gêne : créneau non libre). Pour 11 h–12 h :debut < '12:00' AND fin > '11:00'→ 0 : libre.
Partie B – Les pages PHP (≈ 55 min)
- Place
connexion.phpà côté de tes pages. Écrisreservations.php: affiche, dans un tableau HTML, les réservations d'un jour (paramètrejour, par défaut le 15 mars 2030) avec le nom de la salle, l'association et les heures. Requête préparée ; affichage avechtmlspecialchars. - Écris
reserver.php: reçoit le formulaire de S06 (méthode POST), refait les contrôles (nom, courriel valide, salle, format de date et d'heures, fin après début), refuse un chevauchement (code 409) et sinon insère la réservation (requête préparée).
Tests. Complète :
| Demande | Code attendu | Résultat obtenu |
|---|---|---|
| Salle 1, 15 mars 2030, 10:00 → 12:00 | ||
| Salle 1, 15 mars 2030, 11:00 → 12:00 | ||
| Nom vide, courriel « x », fin avant début |
Je comprends. Pourquoi reserver.php refait-il les contrôles déjà faits par salles.js (S07) ? ______________________
Éléments de réponse
Tests : 10 h–12 h → 409 (« Ce créneau est déjà réservé ») ; 11 h–12 h → 200 (« Réservation enregistrée ») ; saisie invalide → 400 (« Demande invalide »). Le navigateur est sous le contrôle de l'utilisateur : il peut contourner salles.js ou envoyer une requête sans la page. Le serveur ne peut faire confiance qu'à lui-même.
Partie C – L'injection SQL (≈ 40 min)
- Installe
injection-vulnerable.php(laboratoire uniquement). Appelle-la avec?association=Chorale: une ligne. - Appelle-la avec
?association=x' OR '1'='1(adresse encodée par le navigateur). Que se passe-t-il ? ______________________ - Explique pourquoi à partir de la requête finale construite : ______________________
- Corrige la page avec une requête préparée et rejoue la même saisie : résultat ? ______________________
- Avec le compte
portail, essaieDELETE FROM reservations;puis unINSERTavec une fin avant le début : que répond la base ? ______________________
Éléments de réponse
- Toutes les réservations s'affichent, avec les courriels de tout le monde : fuite de données personnelles. 3. La requête devient
… WHERE association = 'x' OR '1'='1': la condition'1'='1'est toujours vraie. 4. Avecprepareetexecute([$association]), la saisie est traitée comme un texte : aucune ligne ne correspond. 5.ERROR 1142 : DELETE command denied(moindre privilège) etERROR 4025 : CONSTRAINT failed(contrainteCHECK (fin > debut)) : la base protège aussi quand le code se trompe.
Partie D – Bilan de sécurité (≈ 25 min, individuel)
Rédige une fiche de revue d'une page : cinq points à vérifier dans une page PHP qui accède à la base (par exemple : requêtes préparées, contrôle serveur, échappement de l'affichage, droits du compte, erreurs non affichées) et, pour chacun, comment tu le vérifies.
Retour en entreprise (si ta situation le permet)
Demande à ton tuteur comment est géré l'accès à la base d'une application de l'entreprise : quel compte, quels droits, où est stocké le mot de passe ? Ne note aucun identifiant réel ; décris seulement la pratique.
Rendu
Archive RENDU-B1A2-S09-NOM.zip : requêtes de la partie A avec résultats, reservations.php, reserver.php, version corrigée de la page vulnérable, réponses de la partie C et fiche de revue (D). Aucun identifiant réel.
Bilan de la séance
Remplis ce bilan seul, honnêtement : il sert à décider ce qu'il faut reprendre. Niveau : Non maîtrisé, Maîtrise partielle, Bonne maîtrise ou Excellente maîtrise (le vocabulaire des grilles nationales d'évaluation), ou Non évalué.
| Compétence du référentiel | Ce que j'ai fait dans cette séance | Niveau |
|---|---|---|
| B1.3 – Développer la présence en ligne de l'organisation | ||
| B1.5 – Mettre à disposition des utilisateurs un service informatique |
Note
Les codes sont ceux du référentiel.
Je sais faire, sans aide :
- Écrire des requêtes SELECT, JOIN et GROUP BY
- Utiliser des requêtes préparées
- Reproduire et corriger une injection SQL
- Appliquer le moindre privilège et le contrôle serveur
Ce que je dois reprendre : ______________________
Ma question à poser à l'enseignant : ______________________