verot / class.upload.php

This PHP class uploads files and manipulates images very easily. It is in fact as much as an image processing class than it is an upload class. Compatible with PHP 4, 5, 7 and 8. Supports processing of local files, uploaded files, files sent through XMLHttpRequest.
http://www.verot.net/php_class_upload.htm
GNU General Public License v2.0
854 stars 359 forks source link

Suggestion: filter the content of svg #172

Closed icret closed 1 year ago

icret commented 1 year ago

SVG uses XML format to define images, so script scripts can be stored internally, thus generating XSS bugs. You want to filter script code from the code side.

Add script code to svg:

<?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 version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
   <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
   <script type="text/javascript">
      alert(document.cookie);
   </script>
</svg>

Short answer filtering is illegal:

if ($handle->file_src_name_ext === 'svg') {
        $svg = file_get_contents($handle->file_src_pathname);
        if (preg_match('/<script[\s\S]*?<\/script>/', $svg)) {
            // do something
        }
    }
icret commented 1 year ago

At the same time, I found that I also need to filter the a tag:

if ($handle->file_src_name_ext === 'svg') {
        $svg = file_get_contents($handle->file_src_pathname);
        if (preg_match('/<script[\s\S]*?<\/script>/', $svg) || stripos($svg, 'href=')) {
        // do something
        }
    }
verot commented 1 year ago

Well, it is not really possible to parse all the files uploaded to filter out these where there may be hidden scripts. Even if we did parse some dangerous SVG, it would give a flase sense of security, since we would probably leave some other dangerous SVG through.