This is my attempt at building a decent SVG sanitizer in PHP. The work is laregely borrowed from DOMPurify.

Overview

svg-sanitizer

Build Status Test Coverage

This is my attempt at building a decent SVG sanitizer in PHP. The work is laregely borrowed from DOMPurify.

Installation

Either require enshrined/svg-sanitize through composer or download the repo and include the old way!

Usage

Using this is fairly easy. Create a new instance of enshrined\svgSanitize\Sanitizer and then call the sanitize whilst passing in your dirty SVG/XML

Basic Example

use enshrined\svgSanitize\Sanitizer;

// Create a new sanitizer instance
$sanitizer = new Sanitizer();

// Load the dirty svg
$dirtySVG = file_get_contents('filthy.svg');

// Pass it to the sanitizer and get it back clean
$cleanSVG = $sanitizer->sanitize($dirtySVG);

// Now do what you want with your clean SVG/XML data

Output

This will either return a sanitized SVG/XML string or boolean false if XML parsing failed (usually due to a badly formatted file).

Options

You may pass your own whitelist of tags and attributes by using the Sanitizer::setAllowedTags and Sanitizer::setAllowedAttrs methods respectively.

These methods require that you implement the enshrined\svgSanitize\data\TagInterface or enshrined\svgSanitize\data\AttributeInterface.

Remove remote references

You have the option to remove attributes that reference remote files, this will stop HTTP leaks but will add an overhead to the sanitizer.

This defaults to false, set to true to remove references.

$sanitizer->removeRemoteReferences(true);

Viewing Sanitization Issues

You may use the getXmlIssues() method to return an array of issues that occurred during sanitization.

This may be useful for logging or providing feedback to the user on why an SVG was refused.

$issues = $sanitizer->getXmlIssues();

Minification

You can minify the XML output by calling $sanitizer->minify(true);.

Demo

There is a demo available at: http://svg.enshrined.co.uk/

WordPress

I've just released a WordPress plugin containing this code so you can sanitize your WordPress uploads. It's available from the WordPress plugin directory: https://wordpress.org/plugins/safe-svg/

Drupal

Michael Potter has kindly created a Drupal module for this library which is available at: https://www.drupal.org/project/svg_sanitizer

TYPO3

An integration for TYPO3 CMS of this library is available as composer package t3g/svg-sanitizer at https://github.com/TYPO3GmbH/svg_sanitizer

Tests

You can run these by running vendor/bin/phpunit from the base directory of this package.

Standalone scanning of files via CLI

Thanks to the work by gudmdharalds there's now a standalone scanner that can be used via the CLI.

Any errors will be output in JSON format. See the PR for an example.

Use it as follows: php svg-scanner.php ~/svgs/myfile.svg

To-Do

More extensive testing for the SVGs/XML would be lovely, I'll try and add these soon. If you feel like doing it for me, please do and make a PR!

Comments
  • XSS bypass using entities and tab

    XSS bypass using entities and tab

    Using payload below to bypass XSS filter:

    <?xml version="1.0" standalone="no"?>
    <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
      <a href="javascript&#9;:alert(document.domain)">
        <circle cx="0" cy="0" r="300"/>
      </a>
    </svg>
    
    

    Video POC: https://www.youtube.com/watch?v=MIAiX4gkp6U&feature=youtu.be

    bug 
    opened by dinhbaouit 10
  • svg attribute sanitizer does not filter out FuncIRI

    svg attribute sanitizer does not filter out FuncIRI

    https://github.com/infinity-next/infinity-next/issues/121#issuecomment-143740026

    http://www.w3.org/TR/SVG/types.html#DataTypeFuncIRI

    Not sure how this could be fixed without castrating the SVG format.

    opened by majestrate 9
  • [BUGFIX] Allow DOMText and implicitly DOMCdataSection

    [BUGFIX] Allow DOMText and implicitly DOMCdataSection

    Recent change disallowed CDATA sections, however the actual fix would have been to disallow non SVG-elements when used inline in some HTML-context.

    Resolves: #70

    opened by ohader 7
  • Check/Remove unused id-attributes

    Check/Remove unused id-attributes

    INPUT

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 145 45">
      <metadata id="metadata"></metadata>
      <g id="whatever">
        <path id="path123"/>
      </g>
    </svg>
    

    OUTPUT

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 145 45">
      <metadata></metadata>
      <g>
        <path/>
      </g>
    </svg>
    
    opened by xerc 5
  • SVG emptied on sanitize

    SVG emptied on sanitize

    So I have an SVG file created as "Export as" in Photoshop CC 2015. Running it through the sanitizer gives the following:

    image

    Is there anything I could do to catch this ?

    Thanks a ton, Andrass

    question 
    opened by AndrassGray 4
  • Improve remote reference detection

    Improve remote reference detection

    This change aims to address some shortcomings of the current remote reference checking method that allows //example.com/folder or ftp://… links to go through for example. I'm more confident using this sanitizer in my project with these changes.

    Tried to follow the formatting of the file, but if something's off with that or the way this was done please let me know.

    opened by SeinopSys 4
  • XML header lines removed

    XML header lines removed

    If you have an SVG files that begins with <?xml version="1.0" encoding="utf-8"?>, then Sanitizer will remove that when saving the clean XML elements back out to the XML file.

    It happens in this line:

    $clean = $this->xmlDocument->saveXML($this->xmlDocument->documentElement, LIBXML_NOEMPTYTAG);
    

    The reason is that all of the XML header info (verison, encoding, etc.) is saved on $this->xmlDocument. Changing that line to:

    $clean = $this->xmlDocument->saveXML($this->xmlDocument, LIBXML_NOEMPTYTAG);
    

    Makes it behave as you'd expect. Just making sure that wasn't a conscious design decision before I submit a pull request.

    opened by angrybrad 4
  • Sanitizer removes too much of data from SVG

    Sanitizer removes too much of data from SVG

    When the attached file is uploaded via this plugin, the arrow on the vertical axis is rotated 90degrees - instead of pointing up it points to the right.

    Original: scheduling.zip

    Sanitized: scheduling-sanitized.zip

    Wrong: screenshot from 2016-11-26 22-46-35

    Correct: screenshot from 2016-11-26 22-48-47

    If's hard to get any useful diff, as the plugin also changes all whitespace in the file...

    bug 
    opened by FreddieChopin 4
  • Change the license type to MIT or to Apache 2.0 or to the double license GPL v2 + MIT or GPL v2 + Apache 2

    Change the license type to MIT or to Apache 2.0 or to the double license GPL v2 + MIT or GPL v2 + Apache 2

    Hi @darylldoyle!

    I hope everything is great.

    We would like to use your library, however we are working on a non-open source software. The current license (GPL v2) is blocking us from using the library.

    Could you please consider changing the license to MIT or to Apache 2.0? Or perhaps having a double license like GPL v2 + MIT or GPL v2 + Apache 2 would be fine for you?

    In that case more software developers will be able to use the library.

    opened by redikultsevsilver 3
  • Removing DOCTYPE breaks entities

    Removing DOCTYPE breaks entities

    Hi,

    not sure if I am doing anything wrong here. The sanitizer removes the DOCTYPE which breaks entities being used, e.g. in this adobe export file. After sanitizing this the file and opening directly in a browser, it produce errors like "Entity 'ns_extend' not defined".

    before

    <?xml version="1.0" encoding="utf-8"?>
    <!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
    	<!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
    	<!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
    	<!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
    	<!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
    	<!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
    	<!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
    	<!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
    	<!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
    ]>
    <svg version="1.1" id="Layer_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
    	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px" height="32px"
    	 viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
    ...
    </svg>
    

    after

    <?xml version="1.0" encoding="utf-8"?>
    <!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
    <svg version="1.1" id="Layer_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
    	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px" height="32px"
    	 viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
    ...
    </svg>
    
    wontfix 
    opened by alex40724 3
  • suspicious node svg

    suspicious node svg

    If there is a doctype then this is reported as an error

    For example take any svg from thesvg 1.1 structural specification

    
    <?xml version="1.0" standalone="no"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    <svg width="8cm" height="3cm"
         xmlns="http://www.w3.org/2000/svg" version="1.1">
      <desc>Local URI references within ancestor's 'defs' element.</desc>
      <defs>
        <linearGradient id="Gradient01">
          <stop offset="20%" stop-color="#39F" />
          <stop offset="90%" stop-color="#F3F" />
        </linearGradient>
      </defs>
      <rect x="1cm" y="1cm" width="6cm" height="1cm" 
            fill="url(#Gradient01)"  />
    
      <!-- Show outline of canvas using 'rect' element -->
      <rect x=".01cm" y=".01cm" width="7.98cm" height="2.98cm"
            fill="none" stroke="blue" stroke-width=".02cm" />
    
    </svg>
    

    This produces the error

                    {
                        "message": "Suspicious node 'svg'",
                        "line": -1
                    }
    
    opened by brianteeman 0
  • [ask] it's possible to use on php 5.6 ?

    [ask] it's possible to use on php 5.6 ?

    Hello i wanna ask my application use php 5.6 when i'm try to install it no show error and when use it not show error also. there are possibility issue when use php 5.6? because i see support package "php": "^7.0 || ^8.0"

    Thanks

    opened by derryberni 3
  • Using library as SVG validator

    Using library as SVG validator

    Hello @darylldoyle thank you for this great library, it works really well.

    I would like to use this library as a validation when uploading a SVG. In general it works ok, but there are some "feature requests" which probably could improve the handling. The use case it, that we want to decide if we allow the upload of the SCG or not not to clean up the uploaded SVG.

    So we tried to sanitize and then check if there are any xmlIssues or if sanitize returns false. So far so good, but we stumbled here over some challenges:

    • If there are PHP opening/closing tags, the sanitizer cleans them, but it's never reported somewhere
    • If there is a comment in the SVG (which is ok I guess) it's reported as xmlIssue here
    • There is no differentiation between the errors a comment raises the same issue level as a javascript
    • It's hard to determinate what error occured just from having the strings (e.g. to output then custom error messages)

    It would be nice to enhance the doc block comments with the description of the parameters and return values.

    Is there anything which is on the roadmap for future releases?

    Thank you in advance.

    opened by frank-miller9 0
Owner
Daryll Doyle
Senior Web Engineer @10up
Daryll Doyle
⚡ Dynamically generated, customizable SVG that gives the appearance of typing and deleting text. Typing SVGs can be used as a bio on your Github profile readme or repository.

⚡ Dynamically generated, customizable SVG that gives the appearance of typing and deleting text. Typing SVGs can be used as a bio on your Github profile readme or repository.

Jonah Lawrence 2k Jan 9, 2023
Upload SVG images in Magento 2.x

Upload SVG images in Magento 2.x This extension for Magento 2 allows uploading SVG images in the following sections: wysiwyg editor in static blocks a

Magegadgets 6 Dec 23, 2022
PHP Exif Library - library for reading and writing Exif headers in JPEG and TIFF files using PHP.

PEL: PHP Exif Library README file for PEL: PHP Exif Library. A library with support for reading and writing Exif headers in JPEG and TIFF images using

null 264 Dec 4, 2022
PHP Image Manipulation

Intervention Image Intervention Image is a PHP image handling and manipulation library providing an easier and expressive way to create, edit, and com

null 13k Jan 3, 2023
PHP 5.3 Object Oriented image manipulation library

Imagine Tweet about it using the #php_imagine hashtag. Image manipulation library for PHP 5.3 inspired by Python's PIL and other image libraries. Requ

Bulat Shakirzyanov 4.3k Jan 6, 2023
🌄 Perceptual image hashing for PHP

ImageHash A perceptual hash is a fingerprint of a multimedia file derived from various features from its content. Unlike cryptographic hash functions

Jens Segers 1.9k Dec 28, 2022
GifCreator is a PHP class that creates animated GIF from multiple images

================================ GifCreator ================================ GifCreator is a PHP class to create animated GIF from multiple images For

Clément Guillemain 320 Dec 15, 2022
GifFrameExtractor is a PHP class that separates all the frames (and their duration) of an animated GIF

================================ GifFrameExtractor ================================ GifFrameExtractor is a PHP class that separates all the frames (an

Clément Guillemain 173 Dec 12, 2022
Image Cache is a very simple PHP class that accepts an image source and will compress and cache the file, move it to a new directory, and returns the new source for the image.

NO LONGER MAINTAINED!!! Image Cache v. 1.0.0 Image Cache is a very simple PHP class that accepts an image source and will compress and cache the file,

Erik Nielsen 455 Dec 30, 2022
PHP Captcha library

Captcha Installation With composer : { ... "require": { "gregwar/captcha": "1.*" } } Usage You can create a captcha with the Captc

Grégoire Passault 1.6k Dec 25, 2022
A BPMN 2.0 workflow engine for PHP

Workflower A BPMN 2.0 workflow engine for PHP Workflower is a BPMN 2.0 workflow engine for PHP. Workflower runs business processes using the BPMN 2.0

PHP Mentors 640 Jan 7, 2023
A Sharex IMG uploader that runs with PHP | Use a hosting site if you're a beginner use 000webhost

Sharex-Img-Uploader A Sharex IMG uploader that runs with PHP | Use a hosting site if you're a beginner use 000webhost Setting up SXCU In YOUR_DOMAIN_U

Pix 10 Nov 26, 2022
A PHP GD + TwitterOAuth demo to dynamically generate Twitter header images and upload them via the API.

A PHP GD + TwitterOAuth demo to dynamically generate Twitter header images and upload them via the API. This enables you to build cool little tricks, like showing your latest followers or sponsors, latest content creted, a qrcode to something, a progress bar for some goal, and whathever you can think of.

Erika Heidi 172 Jan 5, 2023
php-gd based image templates

gdaisy A highly experimental image templating system based on PHP-GD to dynamically generate image banners and covers. Installation 1. Require erikahe

Erika Heidi 67 Nov 22, 2022
Instagram with ImageMagick & PHP

Instagraph - Instagram with ImageMagick & PHP In this repository, I’ll demonstrate you how to create vintage (just like Instagram does) photos effects

Dejan Marjanovic 326 Nov 3, 2022
Grabs the dominant color or a representative color palette from an image. Uses PHP and GD, Imagick or Gmagick.

Color Thief PHP A PHP class for grabbing the color palette from an image. Uses PHP and GD or Imagick libraries to make it happen. It's a PHP port of t

Kevin Subileau 610 Dec 28, 2022
An easy-to-use PHP QrCode generator with first-party support for Laravel.

An easy-to-use PHP QrCode generator with first-party support for Laravel.

Simple Software LLC 2.2k Jan 5, 2023
Get started with the Microsoft Graph SDK for PHP

If you want to play around with the PHP library, you can get up and running quickly with the PHP Connect Sample. This sample will start you with a little Laravel project that helps you with registration, authentication, and making a simple call to the service.

Microsoft Graph 423 Dec 28, 2022