diff --git a/composer.json b/composer.json
index b7518b0e..cbcf92fc 100644
--- a/composer.json
+++ b/composer.json
@@ -8,6 +8,8 @@
"php": "^8.2",
"astrotomic/laravel-translatable": "^11.13",
"doctrine/dbal": "^4.2",
+ "enshrined/svg-sanitize": "^0.16",
+ "ezyang/htmlpurifier": "^4.16",
"hassankhan/config": "^2.2",
"intervention/image": "^3.11",
"ip2location/ip2location-php": "^9.7",
@@ -83,6 +85,10 @@
"test-coverage": "vendor/bin/phpunit --coverage"
},
"config": {
- "sort-packages": true
+ "sort-packages": true,
+ "audit": {
+ "abandoned": "ignore",
+ "block-insecure": false
+ }
}
}
diff --git a/composer.lock b/composer.lock
index 2e3ca0f6..20542f85 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "0adc420e3fbefba6772d5be49b669087",
+ "content-hash": "52bfb1c2bbaa01e1a31818c38bc51165",
"packages": [
{
"name": "astrotomic/laravel-translatable",
@@ -966,6 +966,52 @@
],
"time": "2025-03-06T22:45:56+00:00"
},
+ {
+ "name": "enshrined/svg-sanitize",
+ "version": "0.16.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/darylldoyle/svg-sanitizer.git",
+ "reference": "239e257605e2141265b429e40987b2ee51bba4b4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/darylldoyle/svg-sanitizer/zipball/239e257605e2141265b429e40987b2ee51bba4b4",
+ "reference": "239e257605e2141265b429e40987b2ee51bba4b4",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ezyang/htmlpurifier": "^4.16",
+ "php": "^5.6 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7 || ^6.5 || ^8.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "enshrined\\svgSanitize\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "GPL-2.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Daryll Doyle",
+ "email": "daryll@enshrined.co.uk"
+ }
+ ],
+ "description": "An SVG sanitizer for PHP",
+ "support": {
+ "issues": "https://github.com/darylldoyle/svg-sanitizer/issues",
+ "source": "https://github.com/darylldoyle/svg-sanitizer/tree/0.16.0"
+ },
+ "time": "2023-03-20T10:51:12+00:00"
+ },
{
"name": "ezyang/htmlpurifier",
"version": "v4.19.0",
diff --git a/src/FileManager/MediaRepository.php b/src/FileManager/MediaRepository.php
index fccdba34..4daef17e 100644
--- a/src/FileManager/MediaRepository.php
+++ b/src/FileManager/MediaRepository.php
@@ -159,5 +159,22 @@ public function validateUploadedFile(UploadedFile $file, string $disk): void
if (($maxSize = config("media.disks.{$disk}.max_size", [])) && $file->getSize() > $maxSize) {
throw MediaException::maxFileSizeExceeded($maxSize);
}
+
+ if ($this->isSvg($file)) {
+ $this->sanitizeSvg($file);
+ }
+ }
+
+ protected function isSvg(UploadedFile $file): bool
+ {
+ return in_array($file->getMimeType(), ['image/svg+xml', 'image/svg']) ||
+ $file->getClientOriginalExtension() === 'svg';
+ }
+
+ protected function sanitizeSvg(UploadedFile $file): void
+ {
+ $sanitizer = new \enshrined\svgSanitize\Sanitizer;
+ $cleanSvg = $sanitizer->sanitize(file_get_contents($file->getRealPath()));
+ file_put_contents($file->getRealPath(), $cleanSvg);
}
}
diff --git a/tests/Unit/SvgUploadTest.php b/tests/Unit/SvgUploadTest.php
new file mode 100644
index 00000000..23051163
--- /dev/null
+++ b/tests/Unit/SvgUploadTest.php
@@ -0,0 +1,27 @@
+';
+
+ $file = UploadedFile::fake()->createWithContent('malicious.svg', $svgContent);
+
+ $upload = MediaUploader::make($file)->upload();
+
+ $this->assertTrue(Storage::disk('public')->exists($upload->getPath()));
+
+ $uploadedContent = Storage::disk('public')->get($upload->getPath());
+ $this->assertStringNotContainsString('