Live data from Hacker News

The woes of sanitizing SVGs

muffin.ink

41–50 of 118 posts

Re: The woes of sanitizing SVGs

#41
> In 2019, a few months after the initial release of Scratch 3, Scratch discovered that SVGs can contain tags that Scratch would cause to be executed when the SVG loads. This is known as an XSS.

> Example from Scratch's test suite:

  
  
    
    
  


Is this really an issue? This is the method that the chrome teams polyfill to replace XSLT suggests you do. https://github.com/mfreed7/xslt_polyfill/tree/main#usage

Re: The woes of sanitizing SVGs

#42
Maybe we need a dumbed down version 3 of SVG where the browser knows it is not to do anything that requires fetching a URL, to make the image as harmless as a JPG.

This version 3 could have the version number changed to 2 in order to do cool SVG things, so full-fat SVG as version 2 is now. But you could just flip to 2 to a 3 on upload, so any embedded URLs are harmless.

This could be useful for the creator too, as it is helpful to have layers of source images in bitmap format to work with, and you can easily export such things accidentally.

Re: The woes of sanitizing SVGs

#43
post #4

My first thought is "support a tiny subset of svg that probably still covers 90% of real-world use cases". I do feel that's there's two distinct types of svg - "bunch of paths with fills" and "clever dangerous stuff" where most real SVGs are of the former type. Fully expect this to be shot down by someone that's thought about this problem for longer than the 120 seconds I just spent. :)

Yeah, I think that's the real answer. Look at what Microsoft did with Excel--the dangerous stuff is behind a switch. Thus, solution: Add two bits to the tag. SVG1 does not execute any sort of script. SVG2 does not follow links. SVG3 is actually SVG1 + SVG2 as these are bit flags, not numbers. Additional bits are reserved for future use if any other issues are found. The only real safety is in the engine, not by any s…

What switch?

Re: The woes of sanitizing SVGs

#44
These aren't really SVG specific issues. They are all pretty standard XSS that apply to html and are very well known vectors.

Like this post didn't even mention presentational attributes, like how cursor attribute can contain a url that gets loaded. Or any of the other tricky parts of svg sanitization, like using dtd to bypass things.

Re: The woes of sanitizing SVGs

#45
post #20

I'm glad this article includes the only credible fix for the HTTP leak problems: CSP. A useful thing I learned recently is that, while CSP headers are usually set using HTTP headers, you can also reliably set them directly in HTML - for example for HTML generated directly on a page where HTTP headers don't come into play: "> It feels like this shouldn't work, because JavaScript in the untrusted content could use the…

An idea I’ve been kicking around (which isn’t quite applicable to this use case, I think) is to aggressively restrict the Sec-Fetch- headers on user content. If a server is willing to serve up an untrustworthy SVG, it could refuse to serve it at all unless Sec-Fetch-Dest has the correct value, and ‘document’ and ‘iframe’ would not be correct values. This would make it more difficult to fool a user or their browser by, for example, linking to an SVG file, or using a less-secure mechanism like embed to load it.

This should be in addition to heavily restricting CSP on user content. (Hmm, surely all images should be served with the CSP header set.)

Re: The woes of sanitizing SVGs

#46
post #4

My first thought is "support a tiny subset of svg that probably still covers 90% of real-world use cases". I do feel that's there's two distinct types of svg - "bunch of paths with fills" and "clever dangerous stuff" where most real SVGs are of the former type. Fully expect this to be shot down by someone that's thought about this problem for longer than the 120 seconds I just spent. :)

> My first thought is "support a tiny subset of svg that probably still covers 90% of real-world use cases".

It sounds like the linked post was about someone using a blacklist instead of a whitelist. It doesnt matter how tiny your subset is if you allow through stuff you don't recognize.

For the most part svg is safe. The dangerous parts are pretty obvious - script tag, image tag, feImage tag, attributes starting with on, embedding html in , DTD tricks, namespace tricks, CSS that loads external stuff (keep in mind also presentational attributes. Its not just style attribute/tag).

The rest of it is pretty safe.

Re: The woes of sanitizing SVGs

#47
post #45
post #20

I'm glad this article includes the only credible fix for the HTTP leak problems: CSP. A useful thing I learned recently is that, while CSP headers are usually set using HTTP headers, you can also reliably set them directly in HTML - for example for HTML generated directly on a page where HTTP headers don't come into play: "> It feels like this shouldn't work, because JavaScript in the untrusted content could use the…

An idea I’ve been kicking around (which isn’t quite applicable to this use case, I think) is to aggressively restrict the Sec-Fetch- headers on user content. If a server is willing to serve up an untrustworthy SVG, it could refuse to serve it at all unless Sec-Fetch-Dest has the correct value, and ‘document’ and ‘iframe’ would not be correct values. This would make it more difficult to fool a user or their browser by…

You can bypass the sec-fetch headers via service workers i think.

A better approach here would be to just serve svg with Content-security-policy: script-src 'none'; sandbox

Re: The woes of sanitizing SVGs

#48
post #17

It'd be nice if there was a sandbox attribute you could add to inline tags, like the attribute that'd let you opt out of all the potentially "dynamic" stuff inside of an SVG like scripts and event handlers, or even just literally sandbox the entire thing from accessing the "parent" HTML page's context/cookies/etc just like an iframe. I'm sure it'd just open up a whole other can of worms though... not to mention havin…

I dont see how that could work, as an tag in html is not a document boundry. How can you prevent it from accessing a parent doc when its not a separate document.

There is iframe srcdoc if you want to do this.

Re: The woes of sanitizing SVGs

#49
post #47
post #45

Earlier quoted context omitted.

An idea I’ve been kicking around (which isn’t quite applicable to this use case, I think) is to aggressively restrict the Sec-Fetch- headers on user content. If a server is willing to serve up an untrustworthy SVG, it could refuse to serve it at all unless Sec-Fetch-Dest has the correct value, and ‘document’ and ‘iframe’ would not be correct values. This would make it more difficult to fool a user or their browser by…

You can bypass the sec-fetch headers via service workers i think. A better approach here would be to just serve svg with Content-security-policy: script-src 'none'; sandbox

But you can't make a link to https://your.domain/my_phishing_page.svg work as a phishing page using service workers unless you've pretty thoroughly pwned the site already. (And you can constrain what gets to run as a service worker using Sec-Fetch-Dest!)

I suppose an actual exception is Content-Disposition. If you want the user to save a file, you need to serve it with dest == document as far as I know.

Re: The woes of sanitizing SVGs

#50
post #11
post #4

My first thought is "support a tiny subset of svg that probably still covers 90% of real-world use cases". I do feel that's there's two distinct types of svg - "bunch of paths with fills" and "clever dangerous stuff" where most real SVGs are of the former type. Fully expect this to be shot down by someone that's thought about this problem for longer than the 120 seconds I just spent. :)

It always seems like any animated svg loses all of the animation after sanitizing

There are 3 different methods of animating svgs so it probably depends.
Post reply on HN