Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVG MIME Type (image/svg+xml) is misleading to developers #266

Closed
paragonie-scott opened this issue Sep 13, 2016 · 30 comments
Closed

SVG MIME Type (image/svg+xml) is misleading to developers #266

paragonie-scott opened this issue Sep 13, 2016 · 30 comments

Comments

@paragonie-scott
Copy link

https://www.w3.org/TR/SVGTiny12/mimereg.html

I'd like to propose the deprecation of image/svg+xml as the MIME type to describe SVG files. My reasoning is as follows:

  • SVG files can contain executable code (JavaScript).
  • Developers expect an image/* MIME type to mean data, not code.
  • A failure to separate data from code is a fundamental problem to software security. It turns up in:
    • Buffer overflows
    • SQL injection
    • Cross-site scripting
    • XML External Entities
    • Xpath injection
    • LDAP injection

The end result is that, due to the misleading MIME type for SVG files, most developers who don't know this nuance will accidentally handle them in such a way that makes Stored XSS vulnerabilities possible. It happened to us, and it's been a known problem for years.

The simplest solution is: move to application/svg+xml.

This signals to developers that "this can contain executable code" and also makes naive MIME whitelists (that force a download rather than display/execute directly when a MIME type is absent) based on the image/ prefix less vulnerable.

Alternatively, we could fork into two MIME types:

  • image/svg+xml which is not allowed to contain JavaScript, and if it does, is never executed
  • application/svg+xml which is allowed to contain JavaScript (maybe reserve the svgx file extension for these?)
@gsnedders
Copy link

What practical effect does deprecation of image/svg+xml have, and how does it address concerns about scriptability of the format?

Given the underlying XSS problems are caused by how browsers' implementation of SVG, and merely changing the spec to say image/svg+xml is deprecated does nothing to change their implementation. Realistically, image/svg+xml is unlikely to ever go away. Now, the question is any change can ever be made to the scriptability of that Content-Type, and similarly I suspect that it won't be plausible, which would make any deprecation or reduction in scope unlikely to ever be implemented.

@paragonie-scott
Copy link
Author

I thought the intent would be more clear from the forking suggestion, but the goal is to make image/svg+xml NEVER allow code execution. If you need this "feature", make it available under a separate format (demarcated as "application/foo" rather than "image/foo", possibly as a svgx file rather than svg).

As the standard exists today, it's a security foot-cannon for developers.

@thomassmailus
Copy link

My concern, knowing that there is a valid security concern, is that the security zealots in corporations wanting to clamp everything down... will allow different treatments of different types of the 2-3 types of diagrams that are all SVG graphics, such that the ones with code are marginalized and strangled off by security paranoia.. which would kill the ability to use SVG in many diagram contexts.

@paragonie-scott
Copy link
Author

security zealots
security paranoia

It's difficult to have a level discussion when participants are classified as zealots and ascribed with a mental health disorder right out of the gate.

will allow different treatments of different types of the 2-3 types of diagrams that are all SVG graphics, such that the ones with code are marginalized and strangled off by security paranoia.. which would kill the ability to use SVG in many diagram contexts.

Partitioning into two types still allows SVG (as most people use it) to endure such paranoia.

  • SVG with JavaScript -> arbitrary code execution and a huge risk to the end user; block it!
  • SVG without JavaScript -> no significant risk to the end user, let it through.

As it stands now, the best solution to prevent SVG-assisted stored XSS payloads is to:

  1. Forbid SVG files entirely, or
  2. Cripple their intended functionality (serve as text/plain with no-sniff, force a download, etc.), or
  3. Attempt to write a fork of HTMLPurifier or Stauros that sanitizes SVG files to remove all JavaScript.

1 is the easiest for the backend, but the worst for the frontend. 3 is the easiest for the frontend (you can still use SVG, just not with embedded JS). 2 is what I'm currently doing in my projects, as a stop-gap measure. But eliminating the risk for myself doesn't help address the danger embedded in the standards. Hence, this Github issue.

Most security folks will prefer to just outright forbid all SVG files today when they hear of this risk. Changing the standard doesn't make SVG less acceptable to them. My proposal allows non-ECMAScript-burdened SVG files to still be tolerable by information security professionals.

@gsnedders
Copy link

I thought the intent would be more clear from the forking suggestion, but the goal is to make image/svg+xml NEVER allow code execution.

My intent was to get at how you intend on getting browser vendors to ship that (breaking) change? Browser vendors are unlikely to ship such a breaking change just because the spec has changed (over concern about how many SVGs will be broken as a result), and the security issue exists as long as browsers support script execution on image/svg+xml. Browser vendors are incredibly adverse to breaking content, and changing browsers is going to be far harder than changing the spec here.

@thomassmailus
Copy link

It's difficult to have a level discussion when participants are classified as zealots and ascribed with a mental health disorder right out of the gate.

Implying things not stated by pulling content out of context doesn't help either. Nor does it change the reality experienced on the ground in the corporate world, where we would be passing notes on paper for maximum intellectual property security if they had their way.

  • SVG with JavaScript : this is SVG
  • SVG without JavaScript: this is crippled SVG and makes it useless for smart technical diagrams and documentation.

If SVG is just to be a web graphic arts format and has no desire to become a full vector graphics file format, by all means, fragment away. We can always go WebCGM.

Seems like XSS is a problem with XSS and not SVG with JavaScript. Throwing out the baby with the bathwater is the wrong approach.

@paragonie-scott
Copy link
Author

Seems like XSS is a problem with XSS and not SVG with JavaScript.

SVG with JavaScript is a subset of XSS vulnerabilities.

@paragonie-scott
Copy link
Author

@BigBadaboom
Copy link
Contributor

If anyone is interested in seeing one of these SVG files, someone posted
one to StackOverflow today

http://stackoverflow.com/questions/40710399/malicious-javascript-embeded-in-svg-what-it-does

On 22 November 2016 at 04:42, Scott notifications@github.com wrote:

In the news: http://securityaffairs.co/wordpress/53650/malware/svg-
images-locky.html


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#266 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAzSYAG2AdtCMBk_bEc_TzAnaQYCaPo8ks5rAbvugaJpZM4J7108
.

@nikosandronikos
Copy link
Member

We chatted about this in our telcon on 27th October 2016.

The justification for the suggestion is totally valid. But we think that suggesting a mime type change is unlikely to be accepted. Content Security Policy is the preferred way to tackle these kind of issues.
This work is not in scope of the SVG working group for the next year. Therefore, we suggest raising a thread on the Web Incubator Community Group (WICG), in the SVG category. The WICG is intended as a place to develop ideas prior to standardisation, and it's frequented by most of the spec editors and browser developers. You're likely to get a better discussion on WICG since this topic crosses many technical areas.

@paragonie-scott Are you happy to create a thread on WICG? I would suggest stating the problem (with no implied solution), then if you want to suggest a change to mime types, do that in a follow up post on the thread.

@paragonie-security
Copy link

Content Security Policy is the preferred way to tackle these kind of issues.

That's an additional layer that we use and recommend. The only other reasonable alternative is a massive developer education initiative.

Something like:

DANGER: SVG FILES MAY CONTAIN EXECUTABLE JAVASCRIPT. THIS IS A FEATURE, NOT A BUG

...on every place a developer may learn about them.

@co60ca
Copy link

co60ca commented Jan 16, 2017

I agree that that a CSP would be the better option. Non breaking changes are better.

@homakov
Copy link

homakov commented Mar 15, 2017

I raised this concern in a less breaking view (sandboxing JS within SVG unless opted in) here - https://bugs.chromium.org/p/chromium/issues/detail?id=701523

But if we want to keep it same origin, image/svg+xml must definitely be changed. Also, application/json is not executable too, so text/html+svg would look more dangerous?

Changing name to Scriptable Vector Graphics?

@LinkWorxSeo
Copy link

I have been trying to enable gzip on the .htaccess file. This is what I located: https://www.w3.org/services/svg-server/

@DavidBruchmann
Copy link

On http://www.iana.org/assignments/media-types/media-types.xhtml#text can be seen that text/javascript and text/ecmascript have been marked as obsolete with respect to their replacements application/javascript and application/ecmascript.
So a change is not too unlikely and should be considered for svg in longer term.
Surly it requires involvement in the different forums to realize it and make it working.
The interesting point, and I don't know if there is already a format like that, is that the proposed solution consists of two different mime-types depending on the content. In some kind it exists for svg already too if you consider compressed svgs, but that's not fully comparable perhaps.
Question is if both proposed types can be misused in the kind that a file is labelled as the one but has content of the other type with the target to extend limited rights respectively possibilities.

@DavidBruchmann
Copy link

Another question is if it's advisable to overload the file-extension further than anyway already or if it's not better advisable just to introduce svgs (static svg) as file-extension to express just static content without any javascript. Could be the other way around too by introducing svgd (dynamic svg).
Even both file-extensions could be introduced in favour to eliminate the current svg-extension.
Sorry, just brainstorming here.

@DavidBruchmann
Copy link

The latter proposition would eventually require notation of the mime-type in the svg-element if the code is embedded directly in the html as file-extensions never exist to separate the mime-type. There could be automatic recognition in browsers to omit this requirement but this would show that the new file-extensions are constructions only to satisfy outer (server-, security-)needs and not related to inner functionality.

A clear concept here would be nice as the multimedia-files show already that it can be a big mess and a file-extension like avi is just a container and never allows to see any details about the used codex or required software. So even your player / editor can handle those files it doesn't mean that it can handle each of those files,
So changing file-extensions or mime-types is quite a big effort and impact and should be considered thoughtfully. Therefore the suggestion from @nikosandronikos is perhaps still the best even it needs a bit more explanation to understand how dynamic and static svgs can be treated different.

@DavidBruchmann
Copy link

DavidBruchmann commented Jun 23, 2017

Just seeing that using svg in plural is "svgs", that's the same like I proposed for "static SVG". So the proposition is bad as it can be misinterpreted. If the approach with two file-extensions should be realized another file-extension is advisable, i.e. ssvg (static SVG) and dsvg (dynamic SVG) even that's not sorting nice in alphabetical sorted lists of file-extensions (that was the reason why I placed the characters for the adjectives in the end at beginning).

@ghost
Copy link

ghost commented Jun 23, 2017

@DavidBruchmann You are right that "ssvg" sorts worse than "svgs" but it simply looks way better and more descriptive as well. If this would be to become a thing I would certainly vote for "ssvg".

@DavidBruchmann
Copy link

@PSSGCSim like I said there are reasons to decide against this two-file-extension-solution but if it should be chosen and enough supported then there are still other options like i.e. scgx and svgy where x stands just for executable. Naming is a considerable problem but unimportant if the images are directly embedded in HTML (NOT with the embed-tag!!! but all as one file).
If there seems being a need for two file-extensions respectively mime-types even the language is the same, there is much work to define browser-behavior, perhaps different HTML-Tags with corresponding sub-sets of SVG. Clear is that a script-tag inside a ssvg is not allowed but often svgs are changed by scripts from outside, so there have to be developed rules for script-languages too perhaps. I see a bunch of work realizing this approach ...
I don't have a strong opinion yet about the right way but that depends on the still missing answer from @nikosandronikos too. If the whole sense of the separation can be satisfied without touching svg-standard, mime-definitions or even script-standards then probably it's not worth it to spend too much thoughts on it.

@DavidBruchmann
Copy link

One interesting combination would be to inherit several svgs where some are dynamic but others not.
If someone want to define how browsers shall behave then, and how the code has to look like, that's a bigger issue ...
Sorry, still brainstorming ;-)

@teohhanhui
Copy link

With the same line of reasoning we must have application/html, for sure.

@dstorey
Copy link
Member

dstorey commented May 5, 2018

Closing this based on #266 (comment) suggestion of raising in WICG instead.

@dstorey dstorey closed this as completed May 5, 2018
@paragonie-scott
Copy link
Author

If anyone else want to open this issue elsewhere (e.g. WICG), feel free. I'm done.

@06b
Copy link

06b commented May 7, 2018

IGNOREME: I am commenting here so I can easily find this issue again in the future, since I can't do that by subscribing alone.

@ghost
Copy link

ghost commented Aug 12, 2019

It's difficult to have a level discussion when participants are classified as zealots and ascribed with a mental health disorder right out of the gate.

Implying things not stated by pulling content out of context doesn't help either. Nor does it change the reality experienced on the ground in the corporate world, where we would be passing notes on paper for maximum intellectual property security if they had their way.

  • SVG with JavaScript : this is SVG
  • SVG without JavaScript: this is crippled SVG and makes it useless for smart technical diagrams and documentation.

If SVG is just to be a web graphic arts format and has no desire to become a full vector graphics file format, by all means, fragment away. We can always go WebCGM.

Seems like XSS is a problem with XSS and not SVG with JavaScript. Throwing out the baby with the bathwater is the wrong approach.

Notes on paper. You know, that’s actually not a bad idea. Hold on while I type that into my Excel Spreadsheet on this corporate Windows workstation that is just moments away from any number of yet more MS security flaws. That’s one hella strange infosec dept at your workplace...

@ghost
Copy link

ghost commented Aug 12, 2019

With the same line of reasoning we must have application/html, for sure.

pen/paper

@b-hayes
Copy link

b-hayes commented Dec 5, 2022

I am here reading this after seeing why our ORG decided to block and stop using all svg's across products.
Gmail blocks svgs now too and we had to remove out own ones from automated email systems etc.

Nobody can trust SVG and thus nobody is allowed to use it unless it's their own file served on their own website.

It's a great image format and we can't use it because nobody will take a suggestion like this seriously.
This discussion was not given the merit it deserved.

There are plenty of use cases where you might want to allow an SVG from an external source to be served to users but the risk of them containing javascript is too great to allow it and the default stance by more and more companies to outright block all svg's from these use cases.

@namedgraph
Copy link

@b-hayes have you blocked HTML too?

@b-hayes
Copy link

b-hayes commented Jan 9, 2023

@b-hayes have you blocked HTML too?

yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests