Block SVG uploads for storefront logos/covers/product images.
Deploy Ladill Merchant / deploy (push) Successful in 24s
Deploy Ladill Merchant / deploy (push) Successful in 24s
SVG can embed JavaScript and would run as stored XSS when served inline on a public storefront page, and we have no SVG sanitizer. Allow only raster formats: - item_images validation: image rule (permits SVG) -> mimes:jpeg,jpg,png,gif,webp - QrCodeManagerService: reject image/svg+xml / .svg(z) in brand-image and item-image storage (defense in depth, since those only checked the image/* prefix) - file pickers: accept raster mimes only Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
8b68fad82c
commit
f48592077f
@@ -330,7 +330,7 @@ class QrCodeManagerService
|
||||
continue;
|
||||
}
|
||||
$mime = $file->getMimeType() ?: '';
|
||||
if (! str_starts_with($mime, 'image/')) {
|
||||
if (! str_starts_with($mime, 'image/') || $this->isSvgUpload($file)) {
|
||||
continue;
|
||||
}
|
||||
$subdir = $type === QrCode::TYPE_SHOP ? 'shop-items' : 'menu-items';
|
||||
@@ -472,11 +472,23 @@ class QrCodeManagerService
|
||||
return ['path' => $path, 'type' => $type, 'size' => (int) $file->getSize()];
|
||||
}
|
||||
|
||||
/**
|
||||
* SVG is rejected for customer uploads: it can embed JavaScript and would
|
||||
* execute as stored XSS when served inline on a public storefront page.
|
||||
*/
|
||||
private function isSvgUpload(UploadedFile $file): bool
|
||||
{
|
||||
$mime = strtolower($file->getMimeType() ?: '');
|
||||
$ext = strtolower($file->getClientOriginalExtension() ?: '');
|
||||
|
||||
return $mime === 'image/svg+xml' || $mime === 'image/svg' || $ext === 'svg' || $ext === 'svgz';
|
||||
}
|
||||
|
||||
private function storeMenuBrandImage(User $user, UploadedFile $file, string $subdir): string
|
||||
{
|
||||
$mime = $file->getMimeType() ?: '';
|
||||
if (! str_starts_with($mime, 'image/')) {
|
||||
throw new RuntimeException('Only image files are supported.');
|
||||
if (! str_starts_with($mime, 'image/') || $this->isSvgUpload($file)) {
|
||||
throw new RuntimeException('Logos and images must be PNG, JPG, GIF or WebP (SVG is not allowed).');
|
||||
}
|
||||
|
||||
$ext = $file->getClientOriginalExtension() ?: 'jpg';
|
||||
|
||||
Reference in New Issue
Block a user