From d3e30e55b268b9fce1e8caaea8bead0c9c9c7050 Mon Sep 17 00:00:00 2001 From: matthieu Date: Wed, 22 Apr 2026 19:33:51 +0200 Subject: [PATCH] fix(security) : empeche SeedE2ECommand de tourner hors dev/test + exclusion Docker Cette commande cree un compte admin (e2e.super-admin, isAdmin=true) avec un mot de passe hardcode. Le Dockerfile prod copie src/ verbatim, donc le fichier embarquait un backdoor admin potentiel dans l'image de production. Defense en profondeur sur deux couches independantes : - Garde runtime : execute() refuse tout APP_ENV autre que dev|test et retourne FAILURE avec message explicite. - Filet de build : .dockerignore a la racine exclut le fichier du contexte de build, donc meme si la garde runtime sautait le fichier ne serait pas dans l'image prod. Injecte egalement SiteProviderInterface (Shared) au lieu de SiteRepositoryInterface (Module/Sites) en coherence avec le refactor d'isolation Core/Sites. Co-Authored-By: Claude Opus 4.7 (1M context) --- .dockerignore | 1 + .../Infrastructure/Console/SeedE2ECommand.php | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..7bba432 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +src/Module/Core/Infrastructure/Console/SeedE2ECommand.php diff --git a/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php b/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php index 8acd257..c9bcbb9 100644 --- a/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php +++ b/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php @@ -9,7 +9,7 @@ use App\Module\Core\Domain\Repository\PermissionRepositoryInterface; use App\Module\Core\Domain\Repository\RoleRepositoryInterface; use App\Module\Core\Domain\Repository\UserRepositoryInterface; use App\Module\Core\Domain\Security\SystemRoles; -use App\Module\Sites\Domain\Repository\SiteRepositoryInterface; +use App\Shared\Domain\Contract\SiteProviderInterface; use Doctrine\ORM\EntityManagerInterface; use RuntimeException; use Symfony\Component\Console\Attribute\AsCommand; @@ -50,7 +50,7 @@ final class SeedE2ECommand extends Command private readonly UserRepositoryInterface $userRepository, private readonly RoleRepositoryInterface $roleRepository, private readonly PermissionRepositoryInterface $permissionRepository, - private readonly SiteRepositoryInterface $siteRepository, + private readonly SiteProviderInterface $siteProvider, private readonly UserPasswordHasherInterface $passwordHasher, ) { parent::__construct(); @@ -60,6 +60,17 @@ final class SeedE2ECommand extends Command { $io = new SymfonyStyle($input, $output); + // Garde-fou : cette commande cree un compte admin avec un mot de passe + // hardcode. Elle ne doit JAMAIS tourner hors dev/test, meme si le + // fichier se retrouve embarque dans une image prod par accident (le + // .dockerignore a la racine est la premiere ligne de defense). + $env = $_SERVER['APP_ENV'] ?? 'prod'; + if (!in_array($env, ['dev', 'test'], true)) { + $io->error(sprintf('app:seed-e2e est refuse en environnement "%s". Autorise uniquement en dev/test.', $env)); + + return Command::FAILURE; + } + $userRole = $this->roleRepository->findByCode(SystemRoles::USER_CODE); if (null === $userRole) { @@ -71,7 +82,7 @@ final class SeedE2ECommand extends Command return Command::FAILURE; } - $defaultSite = $this->siteRepository->findByName(self::DEFAULT_SITE_NAME); + $defaultSite = $this->siteProvider->findByName(self::DEFAULT_SITE_NAME); // Pas de fail fatal si le site manque : les tests sidebar/login // n'en dependent pas. Les tests sites-scope-bypass (a venir) le feront.