17 audit site 2026 07 14 - LaurentSta/Oneduc GitHub Wiki

17 — Audit site du 14 juillet 2026

Public : développeurs.

Contexte

Suite à l'audit du 5 juillet 2026, qui avait relevé 8 points à corriger. Cette fiche vérifie l'état de chacun de ces points, corrige ceux qui restaient ouverts, et refait un crawl/validation complet de l'application.

Périmètre consulté

Audit réalisé depuis /var/www/Oneduc_Dev, en environnement local, avec le serveur Laravel lancé sur http://127.0.0.1:8010.

Axe Couverture
Suivi de l'audit précédent Vérification une à une des 8 lignes de 14-audit-site-2026-07-05.md dans le code actuel
Routes php artisan route:list --json
Pages publiques Crawl HTTP des 23 routes GET publiques sans paramètres
Validation php artisan test, npm run build, php artisan migrate:status, php artisan about

Suivi des 8 points de l'audit du 5 juillet

Priorité Point État constaté le 14/07 Action
Haute /inscription en erreur 500 Déjà corrigé le 05/07 (redirection 301 vers /inscription-formateur) Aucune — vérifié par crawl
Haute Test ModuleBuilder rouge Déjà corrigé le 05/07 (test aligné sur le contrat media_id/url) Aucune — vérifié par php artisan test
Haute Connexion stagiaire par code sans throttling Déjà corrigé le 05/07 (rate limiter connexion-code, 10/min/IP) Aucune — vérifié dans AppServiceProvider
Haute Accès module trop large (Module::isVisibleTo()) Partiellement corrigé le 05/07 : la méthode existait mais deux points d'accès ne l'appelaient pas encore. Frontend\LectureController avait été corrigé entre-temps (8/07), StagiaireController::StagiaireModuleDetail() restait ouvert Corrigé aujourd'hui — voir ci-dessous
Haute SCORM legacy écrit last_session_time absent de scorm_scores Déjà corrigé le 05/07 (colonne ajoutée par migration) Aucune — vérifié par migrate:status
Moyenne LessonFeedbackController::store() redirige vers route inexistante Déjà corrigé le 05/07 Aucune
Moyenne FormRequests authorize() = false (StoreModuleRequest, StoreGroupeRequest) Toujours ouvert Corrigé aujourd'hui — voir ci-dessous
Basse Import mort ScormInteractionController Déjà corrigé le 05/07 (retiré avec le correctif S7), mais resté coché comme "à faire" dans la roadmap par oubli de mise à jour de la doc Doc mise à jour, aucun changement de code nécessaire

Sur les 8 points d'origine, 6 étaient déjà résolus. Les 2 restants ont été corrigés dans le cadre de cet audit.


Correctifs appliqués aujourd'hui

1. Faille de sécurité — accès au détail d'un module hors groupe (Haute)

StagiaireController::StagiaireModuleDetail() (route stagiaire.module.detail) chargeait le module avec Module::active()->findOrFail($id) sans jamais vérifier que le stagiaire authentifié appartenait à un groupe auquel ce module est affecté. Un stagiaire pouvait donc consulter le détail, la progression et les objectifs pédagogiques de n'importe quel module actif du site en devinant/énumérant son identifiant dans l'URL — la même classe de faille que celle déjà corrigée sur Frontend\LectureController le 8 juillet.

Correctif : ajout de abort_unless($module->isVisibleTo($user), 403); juste après le chargement du module, dans app/Http/Controllers/StagiaireController.php.

Test ajouté dans tests/Feature/ModuleVisibilityTest.php :

  • a stagiaire with no group assignment cannot open the module detail page of an active module → attend un 403
  • a stagiaire in a group with the module assigned can open the module detail page → attend un 200 (non-régression)

2. FormRequests inutilisables (Moyenne)

StoreModuleRequest::authorize() et StoreGroupeRequest::authorize() retournaient false, ce qui les rend inutilisables (403 systématique) si elles étaient un jour injectées dans un contrôleur — elles ne sont actuellement utilisées nulle part dans le code (StoreModule et GroupeController valident encore en ligne).

Correctif : les deux méthodes retournent désormais true, ce qui aligne ces classes sur la convention déjà en place dans le reste du projet (ContactRequest, LoginRequest, ScormImportRequest) — l'autorisation réelle est du ressort du middleware de route (auth, role:formateur, association.member), pas du FormRequest.

Fichiers modifiés : app/Http/Requests/StoreModuleRequest.php, app/Http/Requests/StoreGroupeRequest.php.


État des routes

php artisan route:list --json retourne 513 routes (411 lors de l'audit du 5 juillet — croissance normale, une dizaine de fonctionnalités livrées depuis : émargement, consommation IA, outils buzzer/vrai-faux/pendu/mémoire, génération IA, etc.).

Espace Nombre de routes
/formateur 208
/admin 135
/stagiaire 53
/observateur 9
Routes publiques, auth partagée, SCORM et outils live 108

Crawl HTTP public

23 routes GET publiques sans paramètres testées (même méthodologie que le 5 juillet).

Statut Nombre Détail
HTTP 200 22 Accueil, catalogue, pages légales, connexion, inscription formateur, contact, nuage de mots public, accès stagiaire, etc.
HTTP 301 1 /inscription → redirection volontaire vers /inscription-formateur

0 erreur HTTP 500. Le crawl public est entièrement sain.


Validations techniques

Commande Résultat
php artisan test 268 tests passés, 0 échec (1295 assertions)
npm run build Réussi, mêmes avertissements Vite qu'au 5 juillet (chunks > 500 kB, directives "use client") — pas de régression
php artisan migrate:status Toutes les migrations marquées Ran, aucune en attente
php artisan about --only=environment,cache,drivers Laravel 11.42.0, PHP 8.3.6, DB MySQL, queue/session/cache database

Points à corriger restants (hors périmètre de cet audit)

Ces points n'étaient pas dans la liste du 5 juillet et restent en dette technique, sans impact de sécurité immédiat :

Priorité Point Localisation
Moyenne attempts_count SCORM jamais incrémenté SCORMController.php
Haute (analytics) scorm_interactions non alimenté pour les leçons SCORMController::saveProgress()
Moyenne Group sans SoftDeletes app/Models/Group.php
Haute (fonctionnel) Stagiaire multi-groupe — .first() uniquement dans StagiaireModules() StagiaireController.php
Maintenance ModuleController (1185 lignes), StagiaireController (794 lignes) Backend/ModuleController.php, StagiaireController.php

Ces éléments sont documentés en détail dans 11-roadmap.md.


Retour au wiki