New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 701523 link

Starred by 5 users

Issue metadata

Status: Assigned
Owner:
Buried. Ping if important.
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac
Pri: 2
Type: Feature



Sign in to add a comment

Make SVG use opaque origins

Reported by homakov@gmail.com, Mar 14 2017

Issue description

UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

Steps to reproduce the problem:
It's a known fact that SVG can contain Javascript. What is less known, is that this javascript is executed on the same origin as the server of the image. 

<svg xmlns="http://www.w3.org/2000/svg"><script>
x=new XMLHttpRequest
x.open('get','/')
x.send()
x.onreadystatechange=function(){
  if(x.readyState==4){
    alert(x.response)
  }
}
</script></svg>

This SVG would send a request to current origin with valid cookies and it would leak sensitive information if uploaded to a service that supports SVG. 

It's extremely unclear for developers to not render inline SVG from same domain since they just think of SVG as Scalable Vector Graphics that is not supposed to run Javascript on their origin.

What is the expected behavior?

What went wrong?
The SVG spec does not explicitly say what origin should be used when SVG document is rendered. Therefore I offer to make the origin opaque/sandboxed and run it just like we run data:image/svg+xml,... URLs. 

It's very unlikely anyone ever had origin-specific code in their SVG files for legitimate reasons - scripts are only there to make the image more "interactive". 

Opaque origins would prevent scenarios like this https://medium.com/@yvoschaap/assembla-security-exploit-session-take-over-fca6697c095a#.pnulfi7ok and many others waiting to be discovered...

Did this work before? N/A 

Chrome version: 56.0.2924.87  Channel: n/a
OS Version: OS X 10.12.3
Flash Version:
 

Comment 1 by homakov@gmail.com, Mar 14 2017

Though it is a security issue it should be made public.

Comment 2 by tsepez@chromium.org, Mar 14 2017

Cc: tsepez@chromium.org nasko@chromium.org
Components: Blink>SecurityFeature
Labels: -Type-Bug-Security -Restrict-View-SecurityTeam Type-Feature
Owner: mkwst@chromium.org
Status: Assigned (was: Unconfirmed)
Agreed, This falls into the category of "security feature".

mkwst@ - do we want to try this?

Comment 3 by mkwst@chromium.org, Mar 15 2017

Cc: pdr@chromium.org f...@opera.com
Components: -Blink>SecurityFeature Blink>SVG Blink>SecurityFeature>SameOriginPolicy
Labels: OS-Android OS-Chrome OS-Linux OS-Windows
I would not be sad if we treated SVG documents as having an opaque origin, but it's not clear to me what the impact would be on legitimate usage. "Interactive" might very well mean "requires a user to be signed-in." *shrug* It might be the case that your intuition is correct, homakov@, but I don't know enough about the ecosystem to make a decision.

CCing pdr@ and fs@, who know more about SVG than I do. We can probably skim through HTTP Archive as well to see what current usage looks like.

Comment 4 by homakov@gmail.com, Mar 15 2017

Not claiming I know how everyone uses SVG, it's not that popular. For most people it's a surprise it can have JS scripts. 

Even if there is marginal number of people enjoying shared origin benefits, they could use it with some opt-in header, I guess?

Comment 5 by jochen@chromium.org, Mar 15 2017

Putting them into an opaque origin also means that scripts can't access the svgdocument from the outside anymore, eg document.open() won't work or any other kind of interaction

Comment 6 by mmoroz@chromium.org, Mar 15 2017

Cc: mmoroz@chromium.org

Comment 7 by f...@opera.com, Mar 15 2017

For the top-level browsing context it would hopefully be unproblematic. For nested browsing contexts it seems extending 'sandbox' to also apply to <object> (and <embed>.) We already do have an even more locked down way of embedding though, which is <img>.

Comment 8 by homakov@gmail.com, Mar 15 2017

If compatibility is main concern, here is how we can do it gracefully:

1. If SVG is rendered on Origin1 using object/embed and served from same origin1 - let it run with same origin

2. Top-level context or if parent domain has different origin - use opaque origin

3. If served with <img> - switch off scripts entirely.
I would like to strongly disagree with this assumption:

"It's very unlikely anyone ever had origin-specific code in their SVG files for legitimate reasons - scripts are only there to make the image more "interactive". "

SVG code needs to run on the correct origin in order to AJAX data files for data visualizations.  It is also often required to load web fonts.  And of course, it is required for scripts to communicate between the interactive SVG and the host HTML page.

Yes, most interactive SVG these days is now done inline in an HTML document, but there are still many reasons for wanting to use a separate SVG file embedded as an <object>. 

If authors are serving SVG as interactive objects, they are intentionally turning JavaScript on.  If you want to restrict certain JavaScript functions, you have all the same sandboxing options as for iframes (where sandboxing is supported).

The security concern comes from SVG served as an image by the web page developers (JavaScript off, additional file fetching off, inert and secure), but then opened in its own tab (suddenly fully functional, including AJAX to the server origin).

If you are allowing non-technical content creators or end users to upload SVG, this possibility therefore creates all the same security concerns as allowing them to upload complete HTML files.  You either need to sanitize the content, or quarantine it on a sub-domain that does not share any private information, or you need to use Content Security Policy headers where supported, and serve fallback content (e.g., PNG snapshots) to older browsers that don't support CSP.

Of course, what most sites chose to do is to not allow end-users to upload SVG.  I would love to see browser and server developers make it easier to create secure SVG servers, for web developers who only want SVG as an image format.  But not at the cost of disabling full SVG functionality for devs who are using it that way.

Comment 10 by homakov@gmail.com, Mar 15 2017

> I would like to strongly disagree with this assumption

I am happy to change my view, if you say SVG badly needs same origin maybe you/anyone can point to some website currently using it? 

What do you think of graceful sandboxing offered in Comment 8? That would break less common embeddable svg, example https://jsfiddle.net/gmsg941r/ - still fixable.

> this possibility therefore creates all the same security concerns as allowing them to upload complete HTML files

That's exactly the problem! No one thinks of SVG (image format) as second HTML - let's admit we failed at naming it. It's not like we upload a .PHP file... 

Comment 11 by homakov@gmail.com, Mar 15 2017

Cross ref - https://github.com/w3c/svgwg/issues/266

I would be fine with enforcing new executable MIME too, either way something must be done.
While I wish we could go back to 1999 and fix the misleading name/mime-type, at this point the best move forward is better education.

HTML has a misleading MIME-type too, but everyone knows that text/html isn't plain text, it's an executable file with same-origin access privileges.

Regarding the proposal from Comment 8:

I'm not sure what your fiddle is supposed to demonstrate.  If it is that arbitrary scriptable SVG can include nuisance code like alert(), the solution is a sandbox attribute:  https://jsfiddle.net/37z7eLmw/. If your concern is that the JSFiddle is revealing the sakurity.com cookie, that is misleading: it is revealed to the end user, but not to the embedding domain's JS code.

There is no security concern from embedding cross-origin interactive SVG; browser cross-origin restrictions prevent information cross over, and is supported universally, and HTML sandboxing prevents nuisance scripts and phishing re-directs in modern browsers.

Also, to clarify: scripts *are* turned off completely when an SVG is embedded as <img>, and always have been, as are additional file fetches. 

The issue is same-origin file access, particularly when the file is viewed directly, without the restrictions imposed by the surrounding page (<img> or a sandbox attribute).

This is only a concern for the domain that is hosting the SVG, not for another domain that is embedding it.  However, your proposal would prevent the cross-origin embedded SVG or stand-alone SVG from accessing asset files from its own origin, without any CSP instructions from that server to do so.  In addition to breaking any site that uses SVG as a stand-alone file, this would mean that you would not be able to embed fully-functional SVG on a web page of a different origin.  This would break SVG for anyone using a separate sub-domain to isolate SVG assets from the main web page domain (which is currently one of the simplest approaches for dealing with same-origin security risks).

(Note: by break SVG, I don't just mean AJAX-ing data files. Lots of asset files used in SVG are only supported if they are on the same origin; fonts and <use> cross-references are the most common.)

I don't do enough big production work to have an example to link to, but I will encourage members of the SVG development community to weigh in.

Comment 13 by homakov@gmail.com, Mar 15 2017

Fiddle is demonstrating nothing actually, only an example of cross-origin embedded SVG. 

I agree breaking such use case isn't great. I wish there was a middle ground between same origin and opaque origin - when you can access all same origin resources but have no access to localStorage/cookies - something like unauthed CORS for everyone by default. 

That unfortunately does not exist and cors requests are too restricted for no reason :(
There is a security problem here, though I have not heard of a real exploit using SVG, only that it's a bee in the bonnet of some security-minded folks (perhaps I missed some incident?).

I generally agree with Amelia on all her points. I'm sympathetic to Homakov's concern, but their solutions don't seem quite appropriate to me.

I would like to find a way to allow SVG to be uploaded and trusted more, in a simple way. I wonder if there could be an additional SVG MIME type, application/svg, that would allow unfettered script execution and access for SVG files, while image/svg+xml could have opaque origins.
This change would also break SVG filters that use external resources via <feImage>, like piping it into <feDisplacementMap>. And currently, Chrome doesn't allow data: URIs for that, since it hasn't implemented all of the Filter Effects security specifications.

Comment 16 by zcorpan@gmail.com, Mar 16 2017

There was a proposal for a sandboxed MIME type for HTML (text/html-sandboxed) but it didn't take off.

Commit that dropped this: https://github.com/whatwg/html/commit/cef842d0ebb31f73695247daf0cf01ae71e99e3d

Comment 17 by zcorpan@gmail.com, Mar 16 2017

Search in github for "window.parent" OR frameElement in SVG files:

https://github.com/search?utf8=✓&l=svg&q="window.parent"+OR+"frameElement"&type=Code&ref=searchresults

First page of result has stuff like

<svg xmlns="http://www.w3.org/2000/svg" version="1.0" viewBox='0 0 56 51' onclick="if (window.frameElement &amp;&amp; window.frameElement.parentNode.nodeName === 'button') window.frameElement.parentNode.click()">

Another example:

https://github.com/Viruliant/Viruliant.GitHub.io/blob/bf5d6b55369edb20f922aca3a97e9f070c685bfa/venn.svg?short_path=f5b0f72 -- venn diagram that looks at <param> from parent.

This seems to be from https://www.w3.org/TR/SVGParamPrimer/ .

So at least it seems it would break things if SVG in <object> were changed to use an opaque origin.

I don't know how to find instances of SVG when used in top-level browsing context. Maybe a use counter could help? (It is possible to search httparchive based on use counter hits.)

Comment 18 by homakov@gmail.com, Mar 16 2017

So let's consider object/embed/iframe as direct authorization to access our origin, and put others into opaque one?

Comment 19 by t...@tobireif.com, Mar 16 2017

Dear Chromium Devs, esteemed Egor,

Are you considering to prevent SVG from loading eg .woff files, even if they're on the same domain? I am using fonts with SVG, and I hope you won't break that.

Example: https://codepen.io/TobiReif/full/ZpERON/

(In this example see "@font-face". There I ref an external domain, but generally I wouldn't have an issue with being required to host assets (eg fonts, CSS, and scripts) on the same domain as the SVG.)

Regarding "scripts are only there to make the image more "interactive"".

SVG is not just an image format. It's a first class web technology like HTML. It can load fonts and CSS and scripts and SVG fragments, for example. SVG can be used as part of serious web-apps. It is not just an image format.

Anyone who is eg hosting arbitrary user-supplied / potentially malicious SVG is required to know what SVG is. That's part of the job if the chosen job is to host user-supplied SVG.

Comment 20 by homakov@gmail.com, Mar 16 2017

If you're showing it with <embed>, it will keep working. Otherwise, you would need to add opt-in header to allow same origin. 

Our job is to sandbox some potentially dangerous uses of SVG and, if needed, let them add a header to turn the functionality back. Nobody is taking it back, just due to poor naming and history, we have to break tiny number of apps for greater good.

Comment 21 by jcd...@gmail.com, Mar 16 2017

As someone who specializes in using SVG as an alternative markup language to HTML I would like to point out that the SVG abilities were put there for a purpose.

If you wish to treat SVG as just an image file and impose restrictions, be aware that you are impeding progress for those that wish to move beyond HTML as the basis for internet presentation.

The two ways of looking at web development language importance are quite different. Just because you are committed to one way of doing things should not condone hobbling others with a different viewpoint.

Established method of web design and an alternative method by language importance.

HTML            SVG
CSS             Javascript
Javascript      HTML
SVG             CSS

Please tread carefully with any changes to SVG, as you may not be seeing the forest through the trees. If your goal is to impede progress, Chromium is already doing a fine job by not fully supporting SVG. See bug:  534601 

Comment 22 by t...@tobireif.com, Mar 17 2017

Requiring all SVG developers (who didn't do anything wrong) to set a header stating that they trust their own content on their own domains - not good. Sure they trust their own content on their own domain. Their content should not be broken by browsers, and they shouldn't be required to set an additional header.

There seem to be a few who accept and publish potentially malicious SVG without ensuring any security precautions, because they were ignorant enough to not know what SVG is. There is not much hope that they're less ignorant now. AFAICS they could simply set the header, and continue to accept and publish arbitrary SVG without implementing any security measures. They didn't care about security in the first place, they could just as well continue to not care about security then. If they are to be educated, much more than a header-requirement will be necessary, including a broad education effort by all browser vendors targeting those specific websites (and future developers as well).

Components: Privacy
Labels: Hotlist-EnamelAndFriendsFixIt
Labels: -Hotlist-EnamelAndFriendsFixIt

Sign in to add a comment