fix(share) : durcissement download (allowlist inline anti-XSS + nosniff) et masquage des erreurs SMB
This commit is contained in:
@@ -39,8 +39,8 @@ class ShareBrowseController extends AbstractController
|
||||
$entries = $this->fileSource->dir($path);
|
||||
} catch (ShareNotConfiguredException) {
|
||||
return new JsonResponse(['error' => 'Share not configured.'], 409);
|
||||
} catch (ShareConnectionException $e) {
|
||||
return new JsonResponse(['error' => $e->getMessage()], 502);
|
||||
} catch (ShareConnectionException) {
|
||||
return new JsonResponse(['error' => 'Unable to reach the file share.'], 502);
|
||||
}
|
||||
|
||||
return new JsonResponse([
|
||||
|
||||
@@ -48,17 +48,19 @@ class ShareDownloadController extends AbstractController
|
||||
$stream = $this->fileSource->read($path);
|
||||
} catch (ShareNotConfiguredException) {
|
||||
return new Response('Share not configured.', 409);
|
||||
} catch (ShareConnectionException $e) {
|
||||
throw new NotFoundHttpException($e->getMessage());
|
||||
} catch (ShareConnectionException) {
|
||||
throw new NotFoundHttpException('File not found.');
|
||||
}
|
||||
|
||||
$name = basename($path);
|
||||
$extension = pathinfo($name, PATHINFO_EXTENSION);
|
||||
$mime = MimeTypes::getDefault()->getMimeTypes($extension)[0] ?? 'application/octet-stream';
|
||||
|
||||
// SVG toujours en attachment (anti-XSS) ; sinon respecte le paramètre demandé.
|
||||
$requested = 'attachment' === $request->query->get('disposition') ? 'attachment' : 'inline';
|
||||
$disposition = 'image/svg+xml' === $mime ? HeaderUtils::DISPOSITION_ATTACHMENT : $requested;
|
||||
// Anti-XSS : seuls des types non exécutables sont servis inline (images hors SVG, PDF).
|
||||
// Tout le reste (HTML, SVG, octet-stream, etc.) est forcé en attachment, même si inline est demandé.
|
||||
$inlineSafe = ('image/svg+xml' !== $mime && str_starts_with($mime, 'image/')) || 'application/pdf' === $mime;
|
||||
$wantInline = 'attachment' !== $request->query->get('disposition');
|
||||
$disposition = ($inlineSafe && $wantInline) ? HeaderUtils::DISPOSITION_INLINE : HeaderUtils::DISPOSITION_ATTACHMENT;
|
||||
|
||||
$response = new StreamedResponse(function () use ($stream): void {
|
||||
if (is_resource($stream)) {
|
||||
@@ -68,6 +70,8 @@ class ShareDownloadController extends AbstractController
|
||||
});
|
||||
$response->headers->set('Content-Type', $mime);
|
||||
$response->headers->set('Content-Disposition', HeaderUtils::makeDisposition($disposition, $name));
|
||||
// Empêche le navigateur de "deviner" un type exécutable à partir du contenu.
|
||||
$response->headers->set('X-Content-Type-Options', 'nosniff');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user