Enabling WordPress to handle SVG files safely

Previously on the CogitActive Saga:
Whether dragging the image file into place or manually browsing for it, every attempt was met with the same unrelenting message: “Something went wrong, please try again.”

Those who follow this blog—or at least this mini-series—may know that my journey to restore clean, minimalist reaction buttons has been anything but straightforward. To make a long story short, the plugin I adopted—Rating Widget—prioritizes emoji-based reactions, which doesn’t align with my preference for text-based engagement. However, it does allow the upload of custom images, so I saw an opportunity to circumvent this limitation by designing my own reaction buttons. The best format for this? Scalable Vector Graphics (SVGs), offering sharp, adaptable designs across all screen sizes.

It should have been simple. Upload the files, integrate the buttons, and move forward. But as I attempted to use my newly crafted SVG images within the plugin (see previous post), I was met with the same unrelenting message: “Something went wrong, please try again.” The real obstacle wasn’t technical failure, but WordPress’s default restrictions on SVG files—a decision rooted in security concerns.

Sorry, you are not allowed to upload this file type.
All right reserved

SVGs are a powerhouse in modern web design, offering crisp visuals that scale effortlessly across devices. Their flexibility makes them invaluable—but also problematic. Despite their undeniable benefits, SVG files come with security risks that have kept WordPress resistant to supporting them by default. This long-standing standoff has left many site owners frustrated, searching for ways to integrate SVGs without compromising security. This post will explore why SVG support in WordPress has been such a contentious topic and, more importantly, how you can safely integrate these versatile graphics into your website.

Unpacking SVG challenges in WordPress

Why SVG files pose security risks

The issues is in the ability to add JavaScript alongside vector information. Theoretically, this means implementing SVG support on your website could open you up to attacks if someone uploads a file containing malicious code.John Hughes

SVG files are not just static visuals like other image formats; they’re code-based graphics written in XML (Extensible Markup Language). Unlike traditional images such as PNGs or JPEGs, SVGs function more like a set of written instructions that browsers interpret to render the image. While this flexibility makes SVGs highly adaptable, it also introduces significant security vulnerabilities. For instance, SVG files can harbor executable scripts 1, which are activated when the SVG is displayed on your website—completely unbeknownst to the end user.

Cross-Site Scripting (XSS) Attacks: This type of attack occurs when malicious scripts are injected into otherwise trusted websites, allowing hackers to steal sensitive information, manipulate website content, or redirect users to phishing sites 2. SVG files are particularly dangerous in this context because they can embed clickable elements and deceptively crafted interfaces, tricking users into interacting with harmful content. XSS attacks are not just theoretical; they are among the most severe threats linked to SVG files. Numerous real-world cases have demonstrated how a single compromised SVG file can lead to catastrophic breaches, jeopardizing user trust and site integrity. With a risk level considered high, XSS remains a critical concern for developers working with SVGs.

XML External Entity (XXE) Injection: The XML structure of SVG files poses another significant risk: XXE injection. This occurs when attackers exploit poorly sanitized files to insert harmful directives or external entities, causing unintended actions during parsing. Such exploits can lead to unauthorized access to sensitive files, server-side request forgery (SSRF), or denial-of-service (DoS) attacks. A notorious example is the “Billion Laughs” exploit, where recursive XML entities overwhelm servers, leading to operational instability or complete service disruption 3. Though less common than XSS, XXE attacks still represent a medium-level risk.

Cybercriminals can weaponize SVG files.

Browser-Specific Risks: Browsers interpret SVG files differently, meaning some may be more susceptible to rendering flaws than others. A maliciously crafted SVG could exploit these inconsistencies to crash a browser or trigger unexpected behavior. While browsers are continually updated to patch vulnerabilities, new risks can emerge. As such, browser-specific SVG risks range from low to medium in severity.

Server-Side Resource Consumption: SVG files can strain server resources, particularly if they contain intricate designs with complex paths and filters. These heavy files can cause rendering delays, and in extreme cases, lead to DoS conditions. While not an attack per se, this is a critical concern for sites relying heavily on SVG-based visuals.

In conclusion, while SVG files offer unparalleled advantages in web design, their potential security risks demand serious attention. Protecting your site requires not only an awareness of these vulnerabilities but also a proactive approach to mitigating them. Without strict security measures, even a single compromised SVG file could act as the weak link that jeopardizes your entire website. This is why WordPress has taken a cautious stance, restricting SVG uploads by default.

SVGs can hide harmful code, posing security risks. That’s why WordPress blocks them by default.

SVGs and WordPress: a historical standoff

The inclusion of SVGs as a supported file type in WordPress has been an ongoing discussion for over a decade. It all began back in 2013 when SVG support was first proposed in a ticket (#24251 (external link)) in the WordPress development tracker. The ticket highlighted the growing popularity of SVGs due to their resolution independence and adaptability—a crucial feature in an era where high-resolution screens were becoming the norm. Despite the clear advantages, the path to incorporating SVGs has been fraught with challenges.

Over the years, the ticket has seen numerous discussions, proposals, and patches, showcasing the community’s commitment to resolving this issue. Developers explored methods such as filtering SVGs through KSES 4 and leveraging third-party libraries like DOMPurify for sanitization. Plugins like Safe SVG emerged as interim solutions, but none of these approaches provided the foolproof security and seamless integration required for inclusion in WordPress core. The challenge lay not only in securing SVG uploads but also in ensuring compatibility across themes and plugins, all while adhering to WordPress’s user-first philosophy.

This persistent standoff serves as a testament to the complexity of the issue. While the WordPress community recognizes the need for SVG support in core, achieving it without compromising security remains an elusive goal. As of today, SVG handling continues to be relegated to plugins, with the platform exercising caution in the absence of a universally accepted solution.

There most likely won’t be any movement on this for a while and sadly that means SVGs won’t be a default upload option anytime soon.Simon Codrington

In 2022, the WordPress Performance Team embarked on an ambitious project to address the lingering SVG issue. As reported by WP Tavern (external link), the team began developing an SVG uploads module within the Performance Lab plugin, allowing users to upload sanitized SVG files and preview them in the Media Library. This approach enabled rigorous testing in real-world scenarios before proposing the functionality for integration into WordPress core. Contributors were optimistic, targeting WordPress 6.2 for its debut.

Fast forward to 2025—and WordPress 6.7.2—SVGs remain absent from core functionality. The resolution of this historical standoff still eludes the community.

Navigating the SVG challenge in WordPress

Adding SVG support to WordPress has long been a contentious issue, tied to concerns about security risks (see above). Yet, for those willing to explore alternatives, there are practical solutions to safely integrate SVG uploads into your site. Whether you choose to manually modify your site’s code or rely on trusted plugins, the key lies in implementing this feature responsibly—balancing functionality with essential safeguards.

Implementing SVG support responsibly is not just optional—it’s essential.

Ensuring secure SVG support through code

Incorporating SVG support into WordPress requires a deliberate approach to balance functionality with security. While the process of enabling this feature is straightforward, ensuring that your website remains protected against potential vulnerabilities demands extra care. By following a few key steps, you can safely integrate SVGs into your site:

  • modify your functions.php file to enable support,
  • sanitize all SVG files before upload, and,
  • where applicable, restrict this capability to specific user roles.

Given that I’ll be the sole uploader of SVG files (as mentioned above), and that every file is crafted personally in Inkscape, one might think security risks don’t apply to me. And in theory, that’s correct—hand-creating my graphics ensures I’m in full control of their content. However, errors can occur, even in the most meticulous workflows, and there’s always the possibility I might rely on an SVG designed by someone else down the road. Better to be safe than sorry, right? This is why I’ve chosen to approach this manual coding process with the utmost care, ensuring no vulnerability—however unlikely—is overlooked.

The Ugly

During my search for a solution to the upload issue, I was determined to find a method from a reliable and authoritative source. Unfortunately, the usual suspects—like WordPress.org—offered nothing useful on the matter. So, I decided to include my web host, SiteGround, in the search terms, hoping to uncover something useful. This led me to an article in their knowledge base titled “How to fix ‘Sorry, you are not allowed to upload this file type’ error in WordPress. (external link)” Given the error message I was encountering (as mentioned earlier), I thought it was worth a look.

To allow the upload, go to Site Tools > Site > File Manager and edit the wp-config.php file for your WordPress, which is usually found in the public_html folder. Above the line ‘That’s all, stop editing! Happy publishing.’ insert the following:

define(‘ALLOW_UNFILTERED_UPLOADS’, true);

Save the changes to the file and you should be able to upload the desired file from your WordPress wp-admin -> Media -> Add New.

This approach, while effective in allowing SVG uploads, raises significant security concerns. The ALLOW_UNFILTERED_UPLOADS constant essentially permits uploading files without WordPress’s usual filtering mechanisms, which are designed to protect against potentially harmful files. By enabling unfiltered uploads, you effectively remove a layer of security that safeguards against malicious files, including compromised SVGs.

Even though I’ve stated that I will be the sole uploader and create SVGs myself, bypassing WordPress’s filtering system can still leave my website exposed to vulnerabilities. For instance, if a mistake occurs during the creation process, or if I am later tempted to upload a third-party SVG file, the lack of filtering could prove risky. Additionally, this method does not sanitize SVG files, which is a crucial step in mitigating their inherent security risks.

To their credit, SiteGround issued a warning, advising users to remove the code immediately after uploading the files to minimize risks. However, while this solution might seem simple and effective, this method’s apparent simplicity comes at a steep cost to security.

Do not use this method—it compromises your website’s security!

The Bad

Among the various methods for enabling SVG support in WordPress, one particular snippet of code seems to be everywhere—featured prominently in countless blog posts, tutorials, and articles. I even found it cited by web hosts—other than my own—(who shall remain nameless) 5. Its prevalence might lead many to believe it’s a go-to solution for uploading SVGs, but as I’ll discuss, its ubiquity is no guarantee of safety or reliability.

function cc_mime_types($mimes) {
 $mimes['svg'] = 'image/svg+xml';
 return $mimes;
}
add_filter('upload_mimes', 'cc_mime_types');

This function introduces SVG support by extending WordPress’s allowed MIME types, which dictate the file formats users can upload. It achieves this by adding 'svg' => 'image/svg+xml' to the $mimes array and then using the add_filter hook to apply this modification to WordPress’s upload_mimes filter. On the surface, this approach appears straightforward and effective, and it doesn’t interfere with WordPress’s default filtering mechanisms for uploads.

However, while this snippet enables the upload of SVG files, it doesn’t address their security risks. As mentioned earlier, SVG files—due to their XML-based structure—can contain malicious code that may compromise your website if they are not properly sanitized. This method leaves the responsibility of ensuring that uploaded SVG files are safe entirely up to the user, which might be fine for someone who exclusively creates and manages their own SVG files (as per my workflow). Yet, as I’ve acknowledged, errors or future reliance on third-party SVGs could introduce vulnerabilities.

In short, this snippet offers functionality 6 but lacks built-in safeguards. Pairing this method with a robust sanitization solution would make it far more reliable for secure SVG handling.

The Good?

Continuing my exploration of (manual) SVG support methods, I came across another approach detailed in an article from my web host’s knowledge base: What is an SVG File? A Beginner’s Guide to Scalable Vector Graphics (external link). Although the article started with a plugin-based solution, it also introduced an alternative for those who prefer not to rely on plugins—a suggestion that resonated with me. There was a detailed tutorial, covering each approach thoroughly and clearly, on how to add the snippet of code directly to the theme’s functions.php file.

// Allow SVG
add_filter( 'wp_check_filetype_and_ext', function($data, $file, $filename, $mimes) {

  global $wp_version;
  if ( $wp_version !== '4.7.1' ) {
 	return $data;
  }

  $filetype = wp_check_filetype( $filename, $mimes );

  return [
  	'ext'         	=> $filetype['ext'],
  	'type'        	=> $filetype['type'],
  	'proper_filename' => $data['proper_filename']
  ];

}, 10, 4 );

function cc_mime_types( $mimes ){
  $mimes['svg'] = 'image/svg+xml';
  return $mimes;
}
add_filter( 'upload_mimes', 'cc_mime_types' );

function fix_svg() {
  echo '<style type= text/css >
    	.attachment-266x266, .thumbnail img {
         	width: 100% !important;
         	height: auto !important;
    	}
    	</style>'; 
} 
add_action( 'admin_head', 'fix_svg' );

WARNING: This method is not recommended; it has no built-in functionality to check the SVG files during upload for malicious code. This check is not available when enabling SVG uploads directly from the functions.php file. If securing SVG uploads was as simple as adding a few lines of code, the team behind WordPress would likely have implemented such a feature by now. The absence of this functionality underscores the complexity of securely supporting SVGs—a challenge that cannot be solved with quick fixes.

Although this method appears to provide a more layered approach to enabling SVG support in WordPress, it still falls short of addressing core security issues. The snippet has three main parts: modifying file-checking mechanisms (with a hardcoded dependency on WordPress version 4.7.1, which risks compatibility issues), extending MIME types (similar to the previous code snippet discussed, enabling SVG uploads without sanitization), and improving SVG display in the admin dashboard (partially addressing usability concerns but failing to enhance security). Again, none of these components tackle the crucial step of sanitizing SVG files, leaving the approach inherently insecure.

This code snippet does a better job of addressing certain usability issues compared to simpler approaches. However, noticing the explicit reference to an older WordPress version (4.7.1) and realizing the apparent age of the code itself didn’t leave me feeling confident about relying on it. While it offered some improvements, the outdated nature and lack of robust security measures ultimately pushed me to keep searching for a more modern and reliable solution…

Sanitizing SVGs—a vital step toward security

When it comes to incorporating SVG files into WordPress securely, sanitization is not just a good idea—it’s a critical necessity. SVG files, due to their XML-based structure, can contain embedded scripts or malicious code that could compromise your website’s security (see above). Even if you’ve implemented measures to limit SVG uploads to yourself or other trusted sources, mistakes can happen during file creation, or you may inadvertently upload a compromised SVG. This is where sanitization steps in.

Sanitization essentially involves cleaning the code to remove anything potentially harmful or unnecessary. It ensures that the SVG file is stripped of malicious scripts while leaving its intended visual design intact. This can be achieved using tools or libraries specifically designed for this purpose. However, while sanitizers are an effective tool for improving security, there are currently no fully integrated methods for incorporating their functionality into WordPress itself.

Right now, there are already several tools you can use to ensure your SVGs are safe, called ‘sanitizers’. However, there are seemingly no good ways to implement their functionality into WordPress currently.John Hughes

One standout solution is Daryll Doyle’s SVG-Sanitizer library, which he describes as an attempt to build a decent SVG sanitizer in PHP. The library can programmatically sanitize SVG files before upload, providing developers with a secure option for managing SVGs. For users who prefer a more hands-on approach, tools like the SVG Sanitizer Test (external link) can be invaluable. This online tool allows you to upload an SVG file and sanitize it manually, giving you peace of mind before the file ever touches your website.

At its core, sanitization serves as a safeguard, ensuring that both trusted and external SVGs are thoroughly cleaned before they are uploaded. It is worth emphasizing that this process should never be skipped, whether you are using a plugin, a library, or manual methods. To keep your site secure, prioritize trusted sources or create your SVGs from scratch, and double-sanitize files whenever possible.

To be continued…


1 Executable means that the script can actively run in the user’s browser whenever the SVG is displayed on a website. Since browsers cannot distinguish trusted scripts from harmful ones, they execute the code without discrimination. ^
2 SVG files, with their ability to embed clickable elements and deceptively designed interfaces, can act as highly effective tools for phishing attacks. These files often disguise harmful content as legitimate, tricking users into interacting with them. Once clicked, users may be redirected to phishing sites designed to steal credentials or install malware. ^
3 SVG files can be manipulated to overload a server’s capacity through DoS attacks like the “Billion Laughs” exploit. This can lead to operational instability or complete service disruption. ^
4 KSES is a PHP-based library used in WordPress to filter and sanitize content, ensuring that potentially harmful HTML or script code is stripped from user input. It employs a strict whitelist approach to allow only predefined elements and attributes, prioritizing security by preventing code injection attacks. ^
5 A notable exception to this widespread practice comes from Kinsta, whose article on SVG File (external link) warns against relying solely on this snippet. They point out that many SVG plugins in the WordPress repository also use this code, enabling SVG uploads but neglecting the necessary safety measures. Their advice is clear: avoid copying this code or downloading the first free SVG plugin you find, as this does not constitute a secure approach. ^
6 While this method offers functionality, it’s worth mentioning that SVG handling in WordPress isn’t fully optimized for display. For instance, the ‘Grid View’ in the media library might not present SVGs in the most streamlined way, potentially affecting usability for those managing large numbers of graphics. There are code snippets available to address this limitation, but I didn’t explore them further, given the more critical security concerns with this approach. ^