[webkit-dev] CSS and CORS

Adam Barth abarth at webkit.org
Sat Oct 27 00:36:39 PDT 2012

On Fri, Oct 26, 2012 at 6:36 PM, Dirk Schulze <dschulze at adobe.com> wrote:
> On Oct 26, 2012, at 9:04 PM, Adam Barth <abarth at webkit.org> wrote:
>> On Fri, Oct 26, 2012 at 9:08 AM, Dirk Schulze <dschulze at adobe.com> wrote:
>>> Hi WebKit folks,
>>> I have a question to origin restriction and CSS. First the context:
>>> CSS Masking[1] aims to combine the two different 'mask' property implementations from WebKit and Firefox. To make it short, 'mask' takes an URL and this can either be a reference to an image, or to an <mask> element:
>>> <svg>
>>>        <mask id="mask">
>>>>>>        </mask>
>>> </svg>
>>> <style>
>>> img {
>>>        mask: url(#mask); /* references an SVG Mask element for masking operation (Firefox), OR */
>>>        -webkit-mask: url(test.png); /" takes a reference to an image and operates the masking with the image (WebKit) */
>>> </style>
>>> <img … />
>>> CSS Masking tries to make both possible in the future.
>>> The problem is, that a <mask> can be in an external SVG file and be referenced by SVG fragments: url(http://external.com/mask.svg#mask). It would still not be sure it the fragment points to a graphical element like a <path> (then the SVG file would be interpreted as image) or if it references a <mask> element, in which case it will be an external resource. You need to download the file and parse it to know that.
>>> Does it matter to know if it is an external resource or image before downloading?
>> Ouch.  That sounds like a bad constraint.  How do you plan to
>> implement that?  I guess you'd need to load the SVG as an SVGImage and
>> then either extract the path or the bitmap depending if there is an
>> element with a given ID?  At what point do you check for the ID?  For
>> example, do you want for DOMContentLoaded, or do you wait to see if an
>> ID gets added by JavaScript executing in the page?  Can mask.svg
>> execute JavaScript?  (Normally we ban the execution of JavaScript
>> inside SVGImage.)
> We could load the external file as a document (similar to iframe), check for the header first, if it is an SVG document we check the element if it is a mask or not. That was at least my naive idea. :)

I don't really understand what you mean.  I think this issue is somewhat tricky.

>>> A <mask> element can have events, which run JavaScript: <mask onload="console.log('CORS? Of course!')">. Running the <mask> element will fire the event, which is maybe a violation against CORS, since the SVG file can come from a different origin.
>> I see!  If the <mask> element can execute JavaScript, then we cannot
>> load the resource in an SVGImage because we forbid JavaScript
>> execution in an SVGImage.  Where do you plan to load mask.svg?
> Yes. But I just learned that Gecko never executes scripts on external resources. External references don't have a browser context in Gecko and therefore don't run JavaScript. Opera does support scripts if it is from the same origin. However, this is unspecified in SVG and I am working towards finding a common and secure solution. The approach from Gecko seems to be sane.

As you've described it, I wouldn't describe this API as sane.  The
nuttiest part seems to be that the external resource is treated as a
bunch of DOM if it contains an element with a given ID but otherwise
is treated as an image.

>>> For images, we don't care about the origin, don't run scripts and don't fire events.
>> Correct.
>>> My question is if we have already an CSS property, widely implemented in WebKit, where CORS matters?
>> CORS is supposed to matter for @font-face.  I'm not sure whether it
>> does in our current implementation.  In any case, it's easy to add
>> CORS support for a load.  You can look at how the crossorigin
>> attribute for <img> works.
>>> When do we decide not to go on with the interpretation of a resource because of violation of CORS? Before we even download the resource? After we may already parsed it?
>> The CORS go/no-go decision happens when we receive the response
>> headers, before we start parsing the resource.
>>> Firefox does care about that before parsing and does not load the entire SVG file if it is from a different origin. Since Firefox does not support image references for 'mask', they always assume that the reference is an external reference and not an image.
>> That seems vastly more sane.  Supporting both images and <mask>
>> elements with the same syntax seems very difficult, if not impossible
>> given the constraints that we need to execute JavaScript for the
>> <mask> case.
> Yes, the scripting part is a bit odd. I think following Gecko and don't allow scripting on any external document seems sane.
>>> Opera does not care about the origin, but scripts are not executed and events don't fire.
>> Can we do that?  Note: You still need to sorry about CORS because this
>> API lets you query for whether a document contains an element of a
>> given ID, which isn't something you're supposed to be able to learn
>> about cross-origin resources.
> It would be a bit like the solution from Gecko, if no browser context, then no script. Gecko added CORS as an additional restriction, which seems to be more secure. clipPath for instance contributes to hit testing.
>>> PS: WebKit has support for 'mask' property with referencing of <mask> elements. Currently, external files are not supported. The mask element must be in the same document.
>> Can we continue to do that?  Referencing external files in this way
>> seems like a bad idea.
> Well, we have this issue with more then just masking. It is the same on filter and clipPath. Something that authors may want to do is putting these resources into one SVG document and reference to this document. Otherwise they would need to copy/paste the resource into every file. Given the fact that SVG resources are supposed to work on HTML elements, this would be a big burden and a blow up the size of documents. What about the ideas above?

This discussion isn't really going anywhere.  I'm happy to answer
specific questions you have and to review patches in connection with
these issues.  If you're asking for my opinion it's that this whole
idea is a ball of nuttiness and fully of security problems.  I don't
think we should support it.


More information about the webkit-dev mailing list