Security Tip: Excluding SVGs from Image Validation!
[Tip #107] Laravel 12 introduced a seemingly minor change - image validation now excludes SVGs by default. π€ Let's take a look at why this is so important! π€

Next up in our series on security-related changes in Laravel 12, we've got a seemingly minor change hiding at the bottom of the Upgrade Guide.
Validation - Image Validation Now Excludes SVGs
The image validation rule no longer allows SVG images by default. If you would like to allow SVGs when using the image rule, you must explicitly allow them:
use Illuminate\Validation\Rules\File;
'photo' => 'required|image:allow_svg'
// Or...
'photo' => ['required', File::image(allowSvg: true)],
At first glance, this appears like a fairly innocent change. SVGs aren't directly compatible with images in a lot of contexts, so making them optional to avoid weird bugs makes sense.
However, let's take a look at the PR from Sander Muller that introduced this change...
Currently, the default image validation rule in Laravel is susceptible to Cross-Site Scripting (XSS) attacks, as it includes SVG files without explicit sanitization. An attacker could upload a malicious SVG file, such as:
<svg xmlns="http://www.w3.org/2000/svg" width="383" height="97" viewBox="0 0 383 97">
<text x="10" y="50" font-size="30" fill="black">XSS Logo</text>
<script>alert('XSS');</script>
</svg>
When rendered directly, this file could execute arbitrary JavaScript, leading to potential data theft, session hijacking, or other malicious behavior.
Oh no... this is bad... π§
SVGs support inline HTML, which includes inline scripts, and our old friend javascript. Hence SVGs allow Cross-Site Scripting (XSS)!
So what we're looking at here is a security fix, designed to close an XSS upload vector.
There are two main scenarios where this could be abused:
- The SVG is loaded onto the page directly as markup within the
HTML.
This is the worst case scenario, as the XSS would execute within an existing page, with full access to the user's account, cookies, etc. This would also affect a wide range of users - anyone visiting the page with the SVG. If this is something like a profile image, it could easily be shown to every active user! Like I said, this is the worst case. - SVG is accessed directly.
The attacker would need to trick their victims to visiting the SVG file directly to trigger the XSS, it won't work inside an<img>
tag. However, when visited, it would still have access to the user's cookies and be able to make HTTP requests to the app, or elsewhere to send the cookies out, but you'd need to get the victim to load the SVG first to trigger the XSS.
Scenario #1 is definitely worse, but it would be fairly easy to use #2 for a targeted attack against specific users. In either case, this is bad, and it's a really good thing this was identified, and SVGs are now disabled by default.
It's also worth pointing out that #2 also needs your images to be hosted on the same domain as your app. If they are on a separate domain, such as file storage or a CDN, the browser won't send your cookies on the request. The XSS will still fire, and may still cause problems in the user's browser, but it won't have cookies to access your app, limiting the potential damage.
My recommendation is to keep SVGs disabled unless you have a very specific business need. If you do need them enabled, run them through a sanitiser to clean out any XSS or other noise, and host them on a dedicated file storage endpoint, so they have no authority over your app.
UPDATE [2025-03-25]
Snipe over on Bluesky pointed me towards a dedicated SVG sanitiser, enshrined/svg-sanitize, which promises to correctly sanitise SVGs for you. I haven't used it personally, but check it out if you need to do so. π
If you found this security tip useful, subscribe to get weekly Security Tips straight to your inbox. Upgrade to a premium subscription for exclusive monthly In Depth articles, or drop a coin in the tip jar to show your support.
When was the last time you had a penetration test? Book a Laravel Security Audit and Penetration Test, or a budget-friendly Security Review!
You can also connect with me on Bluesky, or other socials, and check out Practical Laravel Security, my interactive course designed to boost your Laravel security skills.