src/EventSubscriber/BlockSvgUploadSubscriber.php line 28

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  4. use Symfony\Component\HttpFoundation\File\UploadedFile;
  5. use Symfony\Component\HttpKernel\Event\RequestEvent;
  6. use Symfony\Component\HttpKernel\KernelEvents;
  7. use Symfony\Component\HttpFoundation\Session\Session;
  8. use Symfony\Component\HttpFoundation\RedirectResponse;
  9. /**
  10.  * Bloque les nouveaux uploads SVG:
  11.  *  - Retire tout UploadedFile SVG de la requête avant le binding des formulaires
  12.  *  - Ajoute un flash d'information
  13.  *  - Préserve un fichier déjà existant (champ réédité sans nouveau fichier)
  14.  * Ne touche pas aux SVG historiques déjà stockés (non UploadedFile).
  15.  */
  16. class BlockSvgUploadSubscriber implements EventSubscriberInterface
  17. {
  18.     public static function getSubscribedEvents(): array
  19.     {
  20.         // Priorité faible pour laisser le routage se faire mais avant la validation du formulaire.
  21.         return [KernelEvents::REQUEST => ['onRequest'5]];
  22.     }
  23.     public function onRequest(RequestEvent $event): void
  24.     {
  25.         if (!$event->isMainRequest()) {
  26.             return;
  27.         }
  28.         $request $event->getRequest();
  29.         if (=== count($request->files)) {
  30.             return; // Rien à inspecter
  31.         }
  32.         $foundSvg false;
  33.         $original $request->files->all();
  34.         $cleanSvg = function (&$value) use (&$foundSvg, &$cleanSvg) {
  35.             if ($value instanceof UploadedFile) {
  36.                 if ($value->getMimeType() === 'image/svg+xml') {
  37.                     $foundSvg true;
  38.                     // On retire complètement le fichier (null) pour bloquer l'ajout.
  39.                     $value null;
  40.                 }
  41.             } elseif (is_array($value)) {
  42.                 foreach ($value as $k => $v) {
  43.                     $cleanSvg($value[$k]);
  44.                 }
  45.             }
  46.         };
  47.         foreach ($original as $k => $v) {
  48.             $cleanSvg($original[$k]);
  49.         }
  50.         foreach ($original as $k => $v) {
  51.             $request->files->set($k$v);
  52.         }
  53.         if ($foundSvg) {
  54.             $session $request->getSession();
  55.             if ($session instanceof Session) {
  56.                 $session->getFlashBag()->add(
  57.                     'warning',
  58.                     'Upload SVG bloqué (sécurité). Utilisez PNG ou JPEG.'
  59.                 );
  60.             }
  61.             // Annule le flush / traitement contrôleur: on renvoie l'utilisateur avant l'exécution du contrôleur
  62.             if ($request->isMethod('POST')) {
  63.                 $referer $request->headers->get('referer') ?: $request->getBaseUrl() ?: '/';
  64.                 $event->setResponse(new RedirectResponse($referer303));
  65.             }
  66.         }
  67.     }
  68. }