@@ -602,6 +602,28 @@ private function processFile(Request $request, ResourceNode $resourceNode, Resou
602602 // This covers files uploaded before the MIME-type allowlist was introduced.
603603 $ isSocialAttachment = 'social_post_attachments ' === (string ) $ request ->attributes ->get ('type ' );
604604
605+ // SVG: sanitize before serving in any mode (view or download).
606+ // Glide is raster-only and cannot process SVG; sanitization strips embedded scripts regardless of how the file was stored.
607+ if ('image/svg+xml ' === $ mimeType ) {
608+ $ raw = $ resourceNodeRepo ->getResourceNodeFileContent ($ resourceNode , $ resourceFile );
609+ $ content = (new SvgSanitizer ())->sanitize ((string ) $ raw );
610+
611+ if (false === $ content || '' === $ content ) {
612+ throw new BadRequestHttpException ('Invalid SVG file ' );
613+ }
614+
615+ $ response = new Response ($ content );
616+ $ dispositionMode = 'download ' === $ mode
617+ ? ResponseHeaderBag::DISPOSITION_ATTACHMENT
618+ : ResponseHeaderBag::DISPOSITION_INLINE ;
619+ $ disposition = $ response ->headers ->makeDisposition ($ dispositionMode , $ fileName );
620+ $ response ->headers ->set ('Content-Disposition ' , $ disposition );
621+ $ response ->headers ->set ('Content-Type ' , 'image/svg+xml ' );
622+ $ response ->headers ->set ('X-Content-Type-Options ' , 'nosniff ' );
623+
624+ return $ response ;
625+ }
626+
605627 switch ($ mode ) {
606628 case 'download ' :
607629 $ forceDownload = true ;
@@ -612,28 +634,6 @@ private function processFile(Request $request, ResourceNode $resourceNode, Resou
612634 default :
613635 $ forceDownload = false ;
614636
615- // SVG must not go through Glide (raster-only library); serve directly after sanitization.
616- // Sanitizing at serve time ensures scripts are stripped regardless of how the file was stored.
617- if ('image/svg+xml ' === $ mimeType ) {
618- $ raw = $ resourceNodeRepo ->getResourceNodeFileContent ($ resourceNode , $ resourceFile );
619- $ content = (new SvgSanitizer ())->sanitize ($ raw );
620-
621- if (false === $ content || '' === $ content ) {
622- throw new BadRequestHttpException ('Invalid SVG file ' );
623- }
624-
625- $ response = new Response ($ content );
626- $ disposition = $ response ->headers ->makeDisposition (
627- ResponseHeaderBag::DISPOSITION_INLINE ,
628- $ fileName
629- );
630- $ response ->headers ->set ('Content-Disposition ' , $ disposition );
631- $ response ->headers ->set ('Content-Type ' , 'image/svg+xml ' );
632- $ response ->headers ->set ('X-Content-Type-Options ' , 'nosniff ' );
633-
634- return $ response ;
635- }
636-
637637 // If it's an image then send it to Glide.
638638 if (str_contains ($ mimeType , 'image ' )) {
639639 $ glide = $ this ->getGlide ();
0 commit comments