WordPress blocks SVG uploads by default even though SVG is one of the most useful image formats on the web.
That can seem strange.
SVG files are ideal for assets such as:
- logos;
- icons;
- interface graphics;
- diagrams;
- illustrations;
- other artwork that needs to remain sharp at any resolution.
They can also be extremely small compared with equivalent high-resolution raster images.
So why can you normally upload JPEG, PNG, WebP and AVIF files to the WordPress Media Library, but not an SVG?
The reason is that an SVG is fundamentally different from an ordinary raster image.
An SVG is an XML document. It can contain markup, links, styles, references to external resources and potentially executable behavior.
That makes an untrusted SVG closer to active web content than to a passive collection of pixels.
WordPress therefore does not include SVG in its standard list of permitted image upload types, and WordPress Core does not attempt to sanitize arbitrary SVG files during the normal Media Library upload process.
That distinction is important because simply adding:
image/svg+xml
to the allowed MIME types does not make an uploaded SVG safe.
This guide explains why WordPress blocks SVG uploads, how malicious SVG files can create security problems, why the way an SVG is embedded matters, how sanitization differs from MIME-type validation and how to enable SVG uploads more safely when a WordPress project genuinely needs them.
What is an SVG file?
SVG stands for Scalable Vector Graphics.
Unlike JPEG, PNG, WebP or AVIF images, which primarily store raster pixel information, SVG stores graphical instructions using XML markup.
A very simple SVG might look like this:
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100">
<circle
cx="50"
cy="50"
r="40"
fill="red"
/>
</svg>
The browser interprets those instructions and draws the circle.
SVG graphics are resolution-independent
A raster image has fixed pixel dimensions.
For example:
logo.png
1200 × 400 pixels
Scaling it far beyond those dimensions can eventually make it appear soft or pixelated.
An SVG describes shapes mathematically.
The same vector artwork can therefore render at:
120 × 40
1200 × 400
12000 × 4000
without requiring a new higher-resolution source file.
This makes SVG particularly attractive for responsive websites and high-density displays.
But SVG is not just an image container
This is where the security discussion begins.
An SVG file can contain much more than:
- paths;
- circles;
- rectangles;
- fills;
- strokes.
SVG is part of the browser’s document ecosystem.
Depending on how it is used, an SVG can contain or reference:
- JavaScript;
- event-handler attributes;
- external resources;
- links;
- stylesheets;
- embedded content;
- other SVG documents.
The MDN SVG documentation covers SVG as a browser-native XML graphics language rather than merely another bitmap file format.
WordPress does not allow SVG in its default MIME list
WordPress maintains a list of recognized file extensions and MIME types.
The current wp_get_mime_types() documentation shows the image formats WordPress recognizes by default, including formats such as:
- JPEG;
- GIF;
- PNG;
- BMP;
- TIFF;
- WebP;
- AVIF;
- ICO.
SVG is not in the normal image allowlist.
When WordPress determines which files a user may upload, it uses its allowed MIME-type infrastructure through functions such as get_allowed_mime_types().
That is why WordPress reports the file type as not permitted
If you attempt to upload an SVG through a standard WordPress installation, you may receive a message indicating that you are not allowed to upload that file type.
The important point is that WordPress is blocking the file before treating it like an ordinary Media Library image.
Why SVG files create a different security problem
A JPEG is primarily decoded into pixels.
An SVG is parsed as markup.
That creates an entirely different attack surface.
A malicious SVG may attempt to contain things such as:
- script elements;
- JavaScript URLs;
- event handlers;
- unexpected external resource references;
- dangerous embedded markup;
- malicious CSS or URL references.
Whether a particular payload executes depends heavily on how the SVG is delivered and embedded, but allowing arbitrary unsanitized SVG uploads creates opportunities that do not exist in the same way for ordinary raster images.
An SVG can contain script elements
SVG supports a:
<script>
element.
The MDN SVGScriptElement documentation explicitly discusses SVG script loading and identifies external script URLs as a potential cross-site scripting vector when untrusted data is involved.
A deliberately simplified malicious SVG could conceptually contain:
<svg xmlns="http://www.w3.org/2000/svg">
<script>
// malicious JavaScript
</script>
</svg>
A safe upload system should not simply accept arbitrary script-bearing SVG documents and place them on a public website.
Event-handler attributes are another concern
HTML and SVG elements can expose event-handler attributes such as:
onload
onclick
onmouseover
Depending on context, malicious code may attempt to abuse these handlers.
A sanitizer therefore needs to inspect attributes as well as element names.
Removing only:
<script>
is not sufficient to classify an arbitrary SVG as safe.
How an SVG is embedded changes its security behavior
This is one of the most important details in the entire subject.
An SVG does not behave identically in every browser context.
Consider these different ways to load the same file:
<img src="logo.svg">
background-image: url("logo.svg");
<object data="logo.svg"></object>
<iframe src="logo.svg"></iframe>
They do not necessarily expose the same capabilities.
SVG loaded as an image is more restricted
The MDN guide to SVG as an image explains that browsers impose security restrictions when SVG is used in an image context.
For example, when loaded through an ordinary HTML:
<img>
JavaScript is disabled and external resources are restricted.
This makes:
<img src="trusted-logo.svg" alt="Brand logo">
substantially safer than treating the SVG as an unrestricted document.
Those restrictions do not apply to every context
MDN also points out that the image-context restrictions do not apply in the same way when SVG is loaded as a document through mechanisms such as:
<object>;<embed>;<iframe>;- direct document navigation.
That is why saying:
“SVG scripts cannot run in browsers.”
is incorrect.
A more accurate statement is:
Browser behavior depends on how the SVG is embedded and the security restrictions applied to that context.
SVG files can reference external resources
SVG markup can also include references to other resources.
For example, SVG’s <use> element can reference content from another SVG document.
The MDN documentation for the SVG use element explains how external SVG resources can be referenced through URLs.
Other SVG features can also involve URLs, image references and styles.
External URLs need sanitization too
A sanitizer therefore needs to inspect attributes such as:
href
xlink:href
rather than only checking element names.
A safe SVG workflow may choose to allow:
- local fragment references;
- specific safe data resources;
while removing arbitrary external or executable URL schemes.
SVG can contain embedded HTML-like content
SVG supports advanced features that can significantly expand what exists inside the document.
One example is:
<foreignObject>
which allows other XML namespaces, commonly HTML, to be embedded inside SVG content.
For a basic logo or icon, this type of functionality is almost never necessary.
A security-focused SVG sanitizer may therefore remove advanced elements entirely rather than attempting to preserve every feature permitted by the full SVG specification.
Sanitization usually favors a whitelist
One robust strategy is:
known-safe SVG elements
→ allowed
known-safe SVG attributes
→ allowed
everything else
→ removed
This is generally safer than trying to maintain a blacklist of every dangerous feature that an attacker might use.
Allowing the MIME type is not sanitization
This is probably the most common WordPress SVG mistake.
WordPress exposes the upload_mimes filter, which allows developers to alter which file types can be uploaded.
A commonly seen snippet looks like this:
add_filter( 'upload_mimes', function( $mimes ) {
$mimes['svg'] = 'image/svg+xml';
return $mimes;
} );
This changes permission.
It does not inspect the XML inside the file.
What that snippet actually does
Conceptually:
before:
.svg not allowed
after:
.svg allowed
It does not mean:
malicious elements removed
event handlers removed
unsafe URLs removed
external references inspected
XML structure validated
SVG sanitized
Those are different operations.
File-type validation is also not sanitization
WordPress includes additional file inspection through:
wp_check_filetype_and_ext()
The official wp_check_filetype_and_ext() documentation explains that WordPress attempts to determine the real type of uploaded files and compare it with the filename and allowed MIME types.
This is valuable for reducing file-extension spoofing.
But determining:
this appears to be an SVG file
does not answer:
is the XML inside this SVG safe?
Three separate layers exist
A proper SVG workflow should distinguish:
- Permission: is this user allowed to upload SVG files?
- Type validation: is this file actually consistent with the expected SVG type?
- Content sanitization: does the SVG contain dangerous or unwanted markup?
Passing one layer does not automatically satisfy the other two.
What SVG sanitization should inspect
A serious SVG sanitizer needs to parse the document and evaluate its contents.
Depending on the policy, that may include inspecting or removing:
<script>elements;- event-handler attributes;
- unsafe URL schemes;
- external resource references;
- unexpected embedded content;
- dangerous style constructs;
- unsupported SVG elements;
- unsupported attributes.
Parsing is better than regex replacement
SVG is XML.
Trying to sanitize arbitrary XML using a handful of regular-expression replacements is fragile.
A more appropriate implementation parses the document into a structured representation and then evaluates:
- elements;
- attributes;
- namespaces;
- URLs;
- document structure.
That gives the sanitizer a much better understanding of what the file actually contains.
XML parsing introduces its own security considerations
Because SVG is XML, the sanitizer itself needs to be implemented carefully.
An XML parser should not casually resolve arbitrary external network resources while processing an untrusted upload.
A secure implementation should use parser configuration that prevents unwanted network access and should avoid unsafe external entity behavior.
In PHP-based sanitizers, this is one reason configurations such as:
LIBXML_NONET
can be important when parsing untrusted XML.
The goal is to ensure that the sanitization process does not itself become an attack surface.
Why WordPress Core does not simply sanitize SVG automatically
Sanitizing SVG reliably is considerably more complicated than adding one MIME type.
SVG is a large specification.
There is also a tradeoff between:
- preserving advanced legitimate SVG features;
- removing potentially dangerous functionality.
A strict sanitizer may remove legitimate animation, embedded fonts, complex references or advanced filters.
A permissive sanitizer increases the amount of risky functionality it must evaluate safely.
WordPress Core’s current approach is simpler:
SVG is not included in the standard upload MIME list.
Sites that genuinely need SVG uploads can add a controlled sanitization layer appropriate to their workflow.
Not every SVG is dangerous
It is equally important not to turn the discussion into:
SVG = malware
A normal SVG exported from a trusted vector-design application may contain only ordinary graphical elements such as:
- paths;
- groups;
- fills;
- strokes;
- gradients;
- clip paths.
SVG is not inherently malicious.
The issue is that WordPress cannot assume every uploaded SVG is trustworthy.
Upload permissions matter because WordPress is multi-user software
WordPress may be used by:
- one administrator;
- an editorial team;
- hundreds of contributors;
- customers;
- members;
- users with plugin-defined roles.
Allowing arbitrary SVG uploads has very different implications on a personal portfolio than on a community site where less-trusted users can upload media.
Restrict SVG uploads to trusted users
If a WordPress site enables SVG uploads, consider limiting the capability to users who actually need it.
For example:
- Administrators;
- design staff;
- trusted Editors.
A Contributor writing articles probably does not need unrestricted SVG uploading merely because the design team occasionally uploads logos.
Least privilege reduces exposure
The principle is simple:
user needs SVG uploads
→ allow them
user does not need SVG uploads
→ leave them blocked
Restricting access does not replace sanitization, but it reduces the number of accounts capable of reaching the upload path.
Why ALLOW_UNFILTERED_UPLOADS is not a good SVG solution
WordPress exposes:
ALLOW_UNFILTERED_UPLOADS
but broadly bypassing normal upload restrictions is a much larger change than allowing one carefully controlled format.
If the requirement is:
allow sanitized SVG
the solution should not effectively become:
relax WordPress file restrictions generally
Use the narrowest change necessary for the workflow.
Why SVGZ requires additional caution
SVGZ is a gzip-compressed SVG file.
The underlying content may still represent SVG markup, but compression means the XML cannot simply be inspected as ordinary plain-text SVG without first decompressing it.
A sanitizer designed specifically for regular SVG uploads should not automatically treat:
.svgz
as equivalent to:
.svg
unless it has an explicit, secure SVGZ processing pipeline.
If the project has no genuine need for compressed SVGZ uploads, leaving them blocked is the simpler and safer choice.
SVG dimensions work differently from raster images
SVG also creates Media Library challenges unrelated to security.
Raster images normally have intrinsic pixel dimensions that WordPress can inspect easily.
An SVG may instead rely primarily on:
viewBox="0 0 800 400"
and may not contain conventional:
width
height
attributes at all.
This can affect:
- Media Library previews;
- attachment metadata;
- dimension reporting;
- plugins expecting raster metadata.
WordPress does not generate normal SVG thumbnails
WordPress’s image resizing pipeline is built primarily around raster image processing.
There is generally no reason to create:
150 × 150 SVG
300 × 300 SVG
1024 × 1024 SVG
because the whole purpose of SVG is that the same vector document can scale to different display sizes.
This makes SVG fundamentally different from the thumbnail-generation system described in How WordPress Generates Image Thumbnails.
When SVG is better than PNG or WebP
SVG is particularly useful for graphics that originate as vectors.
Strong use cases include:
- logos;
- icons;
- symbols;
- simple illustrations;
- charts;
- technical diagrams;
- decorative geometric graphics.
SVG remains sharp at every display density
A single SVG logo can display cleanly on:
- small phones;
- desktop monitors;
- Retina displays;
- 4K displays;
- large presentation screens.
You do not need separate 1x, 2x and 3x raster files simply to preserve edge sharpness.
SVG can be extremely small for simple artwork
A simple vector logo may require only a few kilobytes of XML.
Rendering the same graphic as a large transparent PNG could require substantially more data.
When SVG is not the right format
SVG is not a universal image replacement.
It is poorly suited to ordinary photographic imagery.
A photograph is naturally represented as a raster image with millions of pixel color values.
Trying to represent complex photography as vector geometry would generally be impractical.
For photographic content, formats such as:
- AVIF;
- WebP;
- JPEG;
are much more appropriate.
For modern raster-format comparisons, see WebP vs. AVIF vs. JPEG for WordPress.
Inline SVG is different from uploading an SVG attachment
An SVG can also be placed directly inside HTML:
<svg viewBox="0 0 24 24">
...
</svg>
This is called inline SVG.
Inline SVG has useful advantages for developers because CSS and JavaScript can interact directly with its elements.
But that also means arbitrary inline SVG markup from untrusted users requires especially careful sanitization.
Trusted theme SVG and user-uploaded SVG are different threat models
A developer shipping a reviewed icon inside a theme:
theme/assets/icon.svg
is very different from accepting arbitrary SVG documents from unknown users through a public upload form.
Security decisions should reflect where the file came from and who controls it.
Serving SVG with the correct MIME type
SVG files should normally be served as:
image/svg+xml
If a server returns an inappropriate content type, browser behavior and integrations may become inconsistent.
Allowing the extension in WordPress and serving the file correctly are therefore separate pieces of the deployment.
Content Security Policy can provide another layer
A Content Security Policy, or CSP, can restrict which types of resources a page is allowed to execute or load.
The MDN Content Security Policy guide explains how directives can restrict scripts, images, objects and other browser resources.
CSP can be valuable as a defense-in-depth measure.
However:
CSP is not a replacement for SVG sanitization.
An unsafe upload should still be cleaned before it becomes a permanent public asset.
A safer WordPress SVG upload workflow
A more defensible SVG workflow looks like this:
- Restrict SVG uploading to users who actually need it.
- Accept only the intended SVG MIME type and extension.
- Verify that the uploaded file is consistent with SVG.
- Parse the XML using a securely configured parser.
- Prevent unwanted external network access during parsing.
- Allow only approved SVG elements.
- Allow only approved SVG attributes.
- Remove script elements.
- Remove event-handler attributes.
- Remove unsafe URLs and external references according to policy.
- Reject files that cannot be parsed or safely cleaned.
- Store the sanitized version rather than the untrusted original.
Sanitize before public exposure
Do not follow this sequence:
upload untrusted SVG
↓
store publicly
↓
sanitize later
The safer sequence is:
receive upload
↓
validate
↓
sanitize
↓
store safe result
↓
make attachment available
Test the sanitized result visually
Security filtering may change the appearance of complex SVG files.
A sanitizer may remove:
- embedded styles;
- external fonts;
- advanced filters;
- animations;
- unsupported elements.
After implementing an SVG sanitization policy, test representative artwork from the actual design workflow.
The goal is to find a practical safe subset of SVG features that the site genuinely needs.
How TheOneWP handles SVG uploads
TheOneWP’s File Upload Types module allows additional file types to be enabled individually rather than relaxing WordPress’s entire upload policy.
For SVG uploads, the module includes a dedicated sanitization process rather than merely adding:
svg => image/svg+xml
to WordPress’s allowed MIME types.
SVG files are parsed before being stored
The implementation parses SVG as XML using PHP’s DOM infrastructure and disables network access during XML parsing.
This is important because the sanitizer needs to understand the document structure rather than treating it as an opaque text file.
Only approved SVG elements and attributes survive
The sanitizer uses a whitelist-based approach.
Unsupported elements and attributes are removed rather than assuming that unknown SVG functionality is harmless.
Script elements are removed
Elements capable of directly carrying JavaScript are not preserved in sanitized uploads.
Event handlers are removed
Attributes such as:
onclick
onload
are stripped from uploaded SVG markup.
Unsafe URL references are restricted
URL-bearing attributes are checked so that unsafe external or executable references are not simply carried through unchanged.
SVGZ remains blocked
The module deliberately does not treat compressed SVGZ as ordinary SVG because it cannot pass through the same plain SVG inspection path without a dedicated decompression and validation process.
This behavior is intentional rather than an omission. theonewp.WordPress.2026-08-19.xml
Upload access can be restricted by role
SVG permission can also be limited according to the site’s role policy.
This combines two different controls:
who can upload SVG
+
what survives inside the SVG
Neither control replaces the other.
Common mistakes when enabling SVG uploads
Adding only upload_mimes
This enables the extension but performs no SVG content sanitization.
Assuming Administrators can safely upload anything
Administrator-only access significantly reduces risk, but compromised administrator accounts and accidentally sourced files still exist.
Trusted-role restriction is useful defense in depth, not a sanitizer.
Removing only script tags
SVG has more potential active content than one element type.
Attributes, URLs and embedded markup also need consideration.
Using regex as the entire sanitizer
XML should be structurally parsed rather than treated like arbitrary flat text.
Allowing SVGZ automatically
A sanitizer that expects XML cannot inspect a gzip-compressed payload without an explicit decompression step.
Assuming img usage makes unsafe uploads acceptable
An SVG loaded through <img> receives browser restrictions, but the same publicly accessible file may later be opened directly or embedded differently.
Control the uploaded document itself.
Assuming SVGs need normal responsive thumbnails
Vector graphics scale without requiring WordPress’s conventional raster thumbnail matrix.
WordPress SVG security checklist
- Remember that SVG is XML, not merely pixels.
- Do not enable SVG with only a MIME-type snippet on sites accepting untrusted uploads.
- Validate the uploaded extension and MIME type.
- Sanitize SVG content before storing it publicly.
- Use a structured XML parser.
- Disable unnecessary external network access during XML parsing.
- Use an allowlist of permitted elements where practical.
- Use an allowlist of permitted attributes where practical.
- Remove script elements.
- Remove event-handler attributes.
- Inspect URL-bearing attributes.
- Restrict unnecessary external references.
- Consider removing complex embedded markup such as foreign content.
- Restrict SVG upload capability to trusted roles.
- Do not use ALLOW_UNFILTERED_UPLOADS merely to enable one format.
- Do not automatically permit SVGZ unless it has its own safe processing path.
- Serve SVG using the correct MIME type.
- Use CSP as an additional security layer, not as a sanitizer replacement.
- Test sanitized SVG files visually.
- Use SVG mainly for artwork that genuinely benefits from vectors.
Related guides
- Uploading Custom Fonts to WordPress
- Is AVIF Better Than WebP for WordPress Images?
- WebP vs. AVIF vs. JPEG for WordPress
- How WordPress Generates Image Sizes
- How WordPress Generates Image Thumbnails
- Hiding vs. Restricting Access to WordPress Media
- Replacing vs. Re-uploading WordPress Media
- Organizing a Large WordPress Media Library
- Keeping a WordPress Media Library Organized at Scale
Final thoughts
WordPress blocks SVG uploads by default because SVG is not equivalent to a normal raster image.
A JPEG, PNG, WebP or AVIF file primarily gives the browser image data to decode.
An SVG gives the browser an XML document.
That document can contain far more than geometry and colors.
The security model therefore needs to account for:
- scripts;
- event handlers;
- URLs;
- external resources;
- embedded markup;
- the browser context in which the SVG is eventually loaded.
That does not make SVG a bad format.
For logos, icons, diagrams and vector illustrations, it is often the ideal format.
But enabling it correctly requires more than telling WordPress:
.svg is allowed now
The safer model is:
allow only users who need SVG
↓
validate the file
↓
parse the XML securely
↓
sanitize elements and attributes
↓
remove active or unsafe content
↓
store the cleaned result
If your WordPress site needs SVG, enable it deliberately and pair upload permission with real sanitization.
That gives you the scalability and efficiency of vector graphics without pretending an XML document is just another harmless bag of pixels.

