VYPR
Medium severity6.1OSV Advisory· Published Oct 21, 2025· Updated Apr 15, 2026

CVE-2025-61457

CVE-2025-61457

Description

code16 Sharp v9.6.6 is vulnerable to Cross Site Scripting (XSS) src/Form/Fields/SharpFormUploadField.php.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
code16/sharpPackagist
< 9.7.09.7.0

Affected products

1
  • Range: 7.7.2, v4.0-BETA3, v4.0-BETA6, …

Patches

1
bf7fedf2086d

Sanitize SVG

https://github.com/code16/sharpantoineAug 7, 2025via ghsa
11 files changed · +198 9
  • composer.json+1 0 modified
    @@ -19,6 +19,7 @@
             "ext-mbstring": "*",
             "blade-ui-kit/blade-icons": "^1.6",
             "code16/laravel-content-renderer": "^1.1",
    +        "enshrined/svg-sanitize": "^0.21.0",
             "inertiajs/inertia-laravel": "^2.0",
             "intervention/image": "^3.4",
             "laravel/framework": "^11.0|^12.0",
    
  • demo/composer.json+1 0 modified
    @@ -6,6 +6,7 @@
             "bacon/bacon-qr-code": "~2.0",
             "blade-ui-kit/blade-icons": "^1.6",
             "code16/laravel-content-renderer": "^1.2",
    +        "enshrined/svg-sanitize": "^0.21.0",
             "guzzlehttp/guzzle": "^7.2",
             "inertiajs/inertia-laravel": "^2.0",
             "intervention/image": "^3.4",
    
  • demo/composer.lock+47 2 modified
    @@ -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": "c48652e31ba9f176b3c362067dda8c32",
    +    "content-hash": "4d073c5cd646acd5da2c16b5958104c8",
         "packages": [
             {
                 "name": "bacon/bacon-qr-code",
    @@ -759,6 +759,51 @@
                 ],
                 "time": "2025-03-06T22:45:56+00:00"
             },
    +        {
    +            "name": "enshrined/svg-sanitize",
    +            "version": "0.21.0",
    +            "source": {
    +                "type": "git",
    +                "url": "https://github.com/darylldoyle/svg-sanitizer.git",
    +                "reference": "5e477468fac5c5ce933dce53af3e8e4e58dcccc9"
    +            },
    +            "dist": {
    +                "type": "zip",
    +                "url": "https://api.github.com/repos/darylldoyle/svg-sanitizer/zipball/5e477468fac5c5ce933dce53af3e8e4e58dcccc9",
    +                "reference": "5e477468fac5c5ce933dce53af3e8e4e58dcccc9",
    +                "shasum": ""
    +            },
    +            "require": {
    +                "ext-dom": "*",
    +                "ext-libxml": "*",
    +                "php": "^7.1 || ^8.0"
    +            },
    +            "require-dev": {
    +                "phpunit/phpunit": "^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.21.0"
    +            },
    +            "time": "2025-01-13T09:32:25+00:00"
    +        },
             {
                 "name": "fruitcake/php-cors",
                 "version": "v1.3.0",
    @@ -10513,7 +10558,7 @@
         "prefer-stable": true,
         "prefer-lowest": false,
         "platform": {
    -        "php": "^8.2"
    +        "php": "^8.4"
         },
         "platform-dev": {},
         "plugin-api-version": "2.6.0"
    
  • src/Form/Fields/Formatters/UploadFormatter.php+1 0 modified
    @@ -55,6 +55,7 @@ public function fromFront(SharpFormField $field, string $attribute, $value): ?ar
                             disk: $field->storageDisk(),
                             filePath: $formatted['file_name'],
                             shouldOptimizeImage: $field->isImageOptimize(),
    +                        shouldSanitizeSvg: $field->isImageSanitizeSvg(),
                             transformFilters: $field->isImageTransformOriginal()
                                 ? ($value['filters'] ?? null)
                                 : null,
    
  • src/Form/Fields/SharpFormUploadField.php+13 0 modified
    @@ -23,6 +23,7 @@ class SharpFormUploadField extends SharpFormField
         protected ?Dimensions $imageDimensionConstraints = null;
         protected bool $imageCompactThumbnail = false;
         protected bool $imageOptimize = false;
    +    protected bool $imageSanitizeSvg = true;
         protected ?array $imageCropRatio = null;
         protected ?array $imageTransformableFileTypes = null;
     
    @@ -93,6 +94,18 @@ public function isImageOptimize(): bool
             return $this->imageOptimize;
         }
     
    +    public function setImageSanitizeSvg(bool $imageSanitizeSvg = true): self
    +    {
    +        $this->imageSanitizeSvg = $imageSanitizeSvg;
    +
    +        return $this;
    +    }
    +
    +    public function isImageSanitizeSvg(): bool
    +    {
    +        return $this->imageSanitizeSvg;
    +    }
    +
         public function setImageCompactThumbnail(bool $compactThumbnail = true): self
         {
             $this->imageCompactThumbnail = $compactThumbnail;
    
  • src/Http/Jobs/HandleUploadedFileJob.php+11 3 modified
    @@ -21,6 +21,7 @@ public function __construct(
             public string $disk,
             public string $filePath,
             public bool $shouldOptimizeImage = true,
    +        public bool $shouldSanitizeSvg = true,
             public ?array $transformFilters = null,
             public ?string $instanceId = null,
         ) {}
    @@ -45,9 +46,16 @@ public function handle(): void
             if ($this->transformFilters) {
                 // There are transformation and field was configured to handle transformation on the source image
                 HandleTransformedFileJob::dispatchSync(
    -                $tmpDisk,
    -                $tmpFilePath,
    -                $this->transformFilters
    +                disk: $tmpDisk,
    +                filePath: $tmpFilePath,
    +                transformFilters: $this->transformFilters
    +            );
    +        }
    +
    +        if ($this->shouldSanitizeSvg && Storage::disk($tmpDisk)->mimeType($tmpFilePath) === 'image/svg+xml') {
    +            SanitizeSvgJob::dispatchSync(
    +                disk: $tmpDisk,
    +                filePath: $tmpFilePath
                 );
             }
     
    
  • src/Http/Jobs/SanitizeSvgJob.php+35 0 added
    @@ -0,0 +1,35 @@
    +<?php
    +
    +namespace Code16\Sharp\Http\Jobs;
    +
    +use enshrined\svgSanitize\Sanitizer;
    +use Illuminate\Bus\Queueable;
    +use Illuminate\Contracts\Queue\ShouldQueue;
    +use Illuminate\Foundation\Bus\Dispatchable;
    +use Illuminate\Queue\InteractsWithQueue;
    +use Illuminate\Support\Facades\Storage;
    +
    +class SanitizeSvgJob implements ShouldQueue
    +{
    +    use Dispatchable;
    +    use InteractsWithQueue;
    +    use Queueable;
    +
    +    public function __construct(
    +        public string $disk,
    +        public string $filePath,
    +    ) {}
    +
    +    public function handle(): void
    +    {
    +        $sanitizer = new Sanitizer();
    +        $sanitizer->minify(true);
    +        $sanitizer->removeXMLTag(true);
    +        $sanitizedSvg = $sanitizer->sanitize(
    +            Storage::disk($this->disk)->get($this->filePath)
    +        );
    +
    +        Storage::disk($this->disk)
    +            ->put($this->filePath, $sanitizedSvg);
    +    }
    +}
    
  • src/Utils/Uploads/SharpUploadManager.php+2 0 modified
    @@ -30,13 +30,15 @@ public function queueHandleUploadedFile(
             string $disk,
             string $filePath,
             bool $shouldOptimizeImage = true,
    +        bool $shouldSanitizeSvg = true,
             ?array $transformFilters = null,
         ): void {
             $this->uploadedFileQueue[] = compact(
                 'uploadedFileName',
                 'disk',
                 'filePath',
                 'shouldOptimizeImage',
    +            'shouldSanitizeSvg',
                 'transformFilters',
             );
         }
    
  • tests-e2e/site/composer.json+1 0 modified
    @@ -10,6 +10,7 @@
             "ext-json": "*",
             "blade-ui-kit/blade-icons": "^1.7",
             "code16/laravel-content-renderer": "^1.2",
    +        "enshrined/svg-sanitize": "^0.21.0",
             "inertiajs/inertia-laravel": "^2.0",
             "intervention/image": "^3.9",
             "intervention/image-laravel": "^1.3",
    
  • tests-e2e/site/composer.lock+46 1 modified
    @@ -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": "0ba11b09307ec53ce84cc1bb4a3f3c67",
    +    "content-hash": "8688d337ab2efe1f3e1bbd9ed0cc9857",
         "packages": [
             {
                 "name": "blade-ui-kit/blade-icons",
    @@ -700,6 +700,51 @@
                 ],
                 "time": "2024-12-27T00:36:43+00:00"
             },
    +        {
    +            "name": "enshrined/svg-sanitize",
    +            "version": "0.21.0",
    +            "source": {
    +                "type": "git",
    +                "url": "https://github.com/darylldoyle/svg-sanitizer.git",
    +                "reference": "5e477468fac5c5ce933dce53af3e8e4e58dcccc9"
    +            },
    +            "dist": {
    +                "type": "zip",
    +                "url": "https://api.github.com/repos/darylldoyle/svg-sanitizer/zipball/5e477468fac5c5ce933dce53af3e8e4e58dcccc9",
    +                "reference": "5e477468fac5c5ce933dce53af3e8e4e58dcccc9",
    +                "shasum": ""
    +            },
    +            "require": {
    +                "ext-dom": "*",
    +                "ext-libxml": "*",
    +                "php": "^7.1 || ^8.0"
    +            },
    +            "require-dev": {
    +                "phpunit/phpunit": "^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.21.0"
    +            },
    +            "time": "2025-01-13T09:32:25+00:00"
    +        },
             {
                 "name": "fruitcake/php-cors",
                 "version": "v1.3.0",
    
  • tests/Http/Jobs/HandleUploadedFileJobTest.php+40 3 modified
    @@ -119,8 +119,45 @@ public function create()
             ],
         );
     
    -    $this->assertNotEquals(
    -        $originalSize,
    -        Storage::disk('local')->size('data/image.jpg')
    +    expect(Storage::disk('local')->size('data/image.jpg'))->not->toEqual($originalSize);
    +});
    +
    +it('sanitizes svg files', function () {
    +    UploadedFile::fake()
    +        ->createWithContent(
    +            'image.svg',
    +            '<svg xmlns="http://www.w3.org/2000/svg"><script>alert("XSS")</script><rect width="10" height="10"></rect></svg>'
    +        )
    +        ->storeAs('/tmp', 'image.svg', ['disk' => 'local']);
    +
    +    HandleUploadedFileJob::dispatch(
    +        uploadedFileName: 'image.svg',
    +        disk: 'local',
    +        filePath: 'data/image.svg',
    +        shouldOptimizeImage: false,
    +        shouldSanitizeSvg: true,
         );
    +
    +    expect(Storage::disk('local')->get('data/image.svg'))
    +        ->toEqual('<svg xmlns="http://www.w3.org/2000/svg"><rect width="10" height="10"></rect></svg>');
    +});
    +
    +it('does not sanitize svg files if not configured', function () {
    +    UploadedFile::fake()
    +        ->createWithContent(
    +            'image.svg',
    +            '<svg xmlns="http://www.w3.org/2000/svg"><script>alert("XSS")</script><rect width="10" height="10"></rect></svg>'
    +        )
    +        ->storeAs('/tmp', 'image.svg', ['disk' => 'local']);
    +
    +    HandleUploadedFileJob::dispatch(
    +        uploadedFileName: 'image.svg',
    +        disk: 'local',
    +        filePath: 'data/image.svg',
    +        shouldOptimizeImage: false,
    +        shouldSanitizeSvg: false,
    +    );
    +
    +    expect(Storage::disk('local')->get('data/image.svg'))
    +        ->toEqual('<svg xmlns="http://www.w3.org/2000/svg"><script>alert("XSS")</script><rect width="10" height="10"></rect></svg>');
     });
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.