Page MenuHomePhabricator

Rendering SVG images
Open, WishlistPublic

Assigned To
None
Authored By
qgil
Oct 31 2014, 11:33 PM
Tags
Referenced Files
F1098946: security.png
Feb 7 2016, 10:16 PM
F228322: horn_RTL.svg
Nov 1 2014, 7:12 AM
F228215: out.png
Oct 31 2014, 11:56 PM
F228211: Wikimedia-logo.svg
Oct 31 2014, 11:33 PM
Tokens
"Like" token, awarded by volker_e."Like" token, awarded by dnm_t.

Description

Phabricator doesn't render SVG files, and can't thumbnailing them either. This is a pretty usual image file type, we work with them all the time, and having to click 1-2 times, download, render locally is no fun.

  • Original report: https://phabricator.wikimedia.org/T1016 (MediaWiki does render SVGs and generates png thumbnails automatically, so I have asked a couple of our multimedia devs just in case...

    Event Timeline

    qgil raised the priority of this task from to Needs Triage.
    qgil updated the task description. (Show Details)
    qgil added a project: Phabricator.
    qgil added a subscriber: qgil.

    I partially fixed this by adding image/svg+xml to files.viewable-mime-types and files.image-mime-types. In particular:

    • files.viewable-mime-types fixes clicking an SVG, so it renders in the browser instead of downloading.
    • files.image-mime-types fixes the full-sized SVG in Pholio, and embeds with size=full.

    However, we still can't thumbnail SVGs, since gd can't open them.

    Two possible approaches:

    • Since SVGs are scalable, we can produce a "thumbnail" by returning the original file data unmodified, in theory, and produce a visually smaller image with width/height constraints. In practice, this is probably somewhat involved. This also makes SVGs a weird special case, and means that a very large SVG (e.g., an SVG with a lot of complex detail) will have a very large thumbnail in terms of wire size.
    • We may be able to use imagemagick or some other commonly available tool to rasterize SVGs into normal thumbnails, similar to the special handling of animated GIFs.

    It looks like imagemagick can produce a passable thumbnail:

    $ convert -density 8 -resize 100x100 in.svg out.png

    out.png (100×100 px, 7 KB)

    However, it seems to be nontrivial to determine the aspect ratio of an SVG, which we need to produce an accurate thumbnail.

    So we can probably get everything working with stretched-out thumbnails for non-square images pretty easily, but it may be a lot of work to refine thumbnail generation from there.

    Alright, clicking F228322 you go to a page where the SVG is rendered. This saves some clicks. Progress!

    Adding brackets to a file shows nothing to the user. Instead of trying to fix this intermediate state, it is probably better to put the effort in creating the thumbnails.

    One aspect to be careful about with SVGs is security:

    MediaWiki thumbnails SVGs using these external applications https://github.com/wikimedia/mediawiki/blob/master/includes/DefaultSettings.php#L934-L957. The default ImageMagick version seems to be what is used on the WMF production cluster today.

    We also have a lot of code in UploadBase that scans svg content when it is submitted to exclude some of the nastier things that are possible to embed in an svg image.

    @epriestley, we have some code in MW, that parses the xml of the svg, to extract it's viewbox, which you can consider to be a 'original size' and use in the calculations for your target size.

    It's the 2 functions here, that operate on the attributes of the (first) <svg> element in the xml file: http://git.wikimedia.org/blob/mediawiki%2Fcore.git/1cd75dd2b53499aec0e515d8354c353d6949b7cf/includes%2Fmedia%2FSVGMetadataExtractor.php#L338

    We parse out this info on upload, and store it in the DB with the file entry.
    Oh, and on WMF installations, we use librsvg to render SVG, not ImageMagick.

    Looking through the security situation in more detail in response to a recent report via HackerOne, I think it's unlikely that we'll pursue support for this in the upstream. Browsers will execute Javascript and other dangerous actions (external includes, entity expansion) in SVGs, and there is no way to avoid this in a categorical way or otherise delegate security to the browser.

    Mediawiki takes a mostly "blacklist-based" approach to sanitizing SVGs: enumerate all possible badness that can be present in SVGs and disallow it. My experience with these approaches is that they are universally perilous and full of holes (I have never seen one not fail catastrophically, over and over again, until replaced with a whitelist-based system).

    My attempt to briefly review MediaWiki's own track record with SVG security seems to reinforce the idea that this is very complicated, and that "UploadBase" has needed a lot of security fixes, and that there is no particular reason to believe that the code is secure today:

    security.png (1×1 px, 331 KB)

    Here are some tasks I found where SVG support was responsible for security issues (some of these probably overlap with the fixes above -- I'm only briefly glancing at these):

    https://phabricator.wikimedia.org/T85850 - Stored XSS
    https://phabricator.wikimedia.org/T49304 - Stored XSS, I think?
    https://phabricator.wikimedia.org/T59550 - Stored XSS?
    https://phabricator.wikimedia.org/T62771 - Stored XSS?
    https://phabricator.wikimedia.org/T71210 - Denial of Service

    I particularly agree with this comment from UploadBase.php itself:

    @todo Replace this with a whitelist filter!

    Broadly, the risk here seems too large to stomach, especially given the limited benefit and limited interest we've seen.

    As a possible pathway forward, I think it's fairly likely that we'll modularize thumbnail generation code in the future (e.g., for T6674 or T4056). You could then plug in a thumbnailing extension for SVGs based on covert or similar, enable the MIME types per configuration above, and either accept the security risks (which I believe are limited to user tracking/redirection/DOS, not account compromise/CSRF), or possibly fork to add a call to a sanitizer (although this is probably very complicated).

    epriestley triaged this task as Wishlist priority.Feb 7 2016, 10:20 PM

    This isn't necessarily "won't ever fix", but the cost to secure SVG sufficiently is enormous and I can't imagine it making sense to pursue until we are a huge organization with as many as 4 or 5 full time engineers.

    eadler added a project: Restricted Project.Jul 10 2016, 3:30 AM

    (For completeness, this came up via the support queue in PHI411.)

    Also relevant: