W3C home > Mailing lists > Public > public-webappsec@w3.org > April 2019

Re: characterizing framing security needs for webappsec consideration

From: Ojan Vafai <ojan@google.com>
Date: Thu, 18 Apr 2019 11:59:34 -0700
Message-ID: <CANMdWTt-=f5cGLhtSF0T-CDATD=OjSkn3CZhy7TwcBZT28dszA@mail.gmail.com>
To: Ian Clelland <iclelland@google.com>, Rouslan Solomakhin <rouslan@google.com>
Cc: Jeff Hodges <jdhodges@google.com>, Web Application Security Working Group <public-webappsec@w3.org>
This seems far more general than disallowing some specific features, e.g.
you also need to guard against click-jacking, right? Could you meet the
same need in a more general way with IntersectionObserver v2 to ensure that
your UI is visible to the user the way you expect or X-Frame-Options if you
want to just not be embeddable?

Ian Clelland wrote:

> That's definitely not an attack scenario we'd considered (or that I've
> considered) extensively. What you're suggesting is that a site may want to
> use a feature when at the top level, but wants to have itself restricted
> when it is embedded. X-Frame-Options can certainly be used to prevent
> embedding all together, and https://good-site.com has other options to
> detect this and protect itself if it is important -- checking window.parent
> === window to know that it has been framed is one way; I'm sure there are
> others.
>
>
>
> On Wed, Apr 17, 2019 at 10:01 AM Rouslan Solomakhin <rouslan@google.com>
> wrote:
>
>>
>>
>> On Wed, Apr 17, 2019 at 1:08 AM Ian Clelland <iclelland@google.com>
>> wrote:
>>
>>> Hi Jeff,
>>>
>>> PaymentRequest was actually one of the very first features to utilize
>>> Feature Policy in Chrome -- by design, it should be able to handle allowing
>>> and restricting that API in same- and cross-origin embedding scenarios.
>>> I've added more detailed comments inline, but the shortest answer is that
>>> this *should* all work the way Rouslan has described, and that yes, we may
>>> need to add something to the spec if we want to *require* an opt-in from
>>> the embedded page.
>>>
>>> On Tue, Apr 16, 2019 at 8:56 PM Jeff Hodges <jdhodges@google.com> wrote:
>>>
>>>> HI WebAppSec folk,
>>>>
>>>> I've been corresponding with Rouslan over in the Web Payments working
>>>> group regarding Feature Policy in cross-origin iFrames and sandboxed
>>>> iFrames and how they might be used for a couple of use cases he/they have.
>>>> It would seem to have relevance for the still-to-be addressed question of
>>>> policies wrt WebAuthn in cross-origin iFrames.
>>>>
>>>> This is kinda long, but this stuff is complex. I'll try adding it to
>>>> the end of the agenda for tomorrow's call...
>>>>
>>>> On Tue, Apr 16, 2019 at 6:52 AM Rouslan Solomakhin <rouslan@google.com>
>>>> wrote:
>>>>
>>>>> Thank you for the reply, Jeff! Please see my comments inline.
>>>>>
>>>>> On Mon, Apr 15, 2019 at 9:46 PM Jeff Hodges <jdhodges@google.com>
>>>>> wrote:
>>>>>
>>>>>>
>>>>>> On Wed, Apr 3, 2019 at 5:31 PM Rouslan Solomakhin <rouslan@google.com>
>>>>>> wrote:
>>>>>>
>>>>>>> Here's a summary of the needs/considerations for the Web Payment
>>>>>>> APIs:
>>>>>>>
>>>>>>> *#1: Would it be possible to disable certain powerful APIs (e.g.,
>>>>>>> Payment Request and Payment Handler) in embedded cross-origin iframes by
>>>>>>> default, unless the embedded iframe explicitly allows to be embedded for
>>>>>>> the purpose of payments?* Concretely, this could be something like
>>>>>>> a <meta allow-when-embedded="payments"> tag, for example.
>>>>>>>
>>>>>>
>>>>>> *In my reading of Feature Policy
>>>>>> <https://w3c.github.io/webappsec-feature-policy/>, it seems this use case
>>>>>> is addressed*.  For embedding origin example-embedding.foo, and
>>>>>> embedded origin example-embedded.bar, the embedding webapp would
>>>>>> declare on the embedded iframe:
>>>>>>
>>>>>> `<iframe allow="payment example-embedded.bar" ...>`
>>>>>>
>>>>>> and example-embedded.bar would return a "header policy" (from which
>>>>>> the UA forms the embedded content's "declared policy"), like so:
>>>>>>
>>>>>> `Feature-Policy: payment 'self';`
>>>>>>
>>>>>> And then the magic Feature Policy algorithm Is feature enabled in
>>>>>> document for origin
>>>>>> <https://w3c.github.io/webappsec-feature-policy/#algo-is-feature-enabled>
>>>>>>  combines the two policy declarations and comes up with "Enabled"
>>>>>> for the "payment" feature in the cross-origin iframe.
>>>>>>
>>>>>
>>>>> Is my understanding correct that example-embedded.bar does not have
>>>>> to specify a "header policy" for payments to work?
>>>>>
>>>>
>>>> I *think* the answer is "no" because this use case is explicitly
>>>> cross-origin (however, see below).  I think the answer is "yes" if it were
>>>> a same-origin use case.
>>>>
>>>
>>> As currently specced, Feature Policy does *not* require
>>> example-embedded.bar to declare a policy through HTTP headers in order to
>>> use PaymentRequest. If PaymentRequest is allowed in the embedding document
>>> by its own feature policy, and it uses an iframe tag like the one above,
>>> then it will also be allowed in the embedded document.
>>>
>>> By the spec, when the embedded document is created, we will define an
>>> inherited policy for it, using the embedding document's policy and the
>>> container policy constructed from the iframe element. In this case, the
>>> inherited policy for the "payment" feature will be Enabled. Without a
>>> Feature-Policy header, the embedded document's policy will not have a
>>> declared policy for the "payment" feature.
>>>
>>> With that policy in place, when the embedded document tries to use
>>> PaymentRequest, it should call Is feature enabled in document for origin
>>> <https://w3c.github.io/webappsec-feature-policy/#algo-is-feature-enabled>
>>> with its own document and its own origin as arguments. Because the
>>> inherited policy is "Enabled", and the feature is *not* present in the
>>> declared policy, that algorithm will fall through to step 5, discover that
>>> "origin" is same origin-domain with document's origin (the origins should
>>> be identical because of how it was called), and return True.
>>>
>>>
>>>
>>>> So, upon further grovelling thru the Feature Policy spec, I am unsure
>>>> whether it can be employed to allow cross-origin feature use. The spec
>>>> seems unclear whether the Should request be allowed to use feature
>>>> <https://w3c.github.io/webappsec-feature-policy/#algo-should-request-be-allowed-to-use-feature> alg
>>>> is invoked in the case where JS running in the embedded frame invokes
>>>> PaymentRequest ?
>>>>
>>>
>>> I'm not sure which spec you mean when you say that it is unclear -- I'll
>>> explain the specs as I understand the relationship, but I'd be happy to
>>> make changes where I can to make it clearer:
>>>
>>> The Payment Request API spec says that the PaymentRequest constructor
>>> <https://www.w3.org/TR/payment-request/#constructor> should call HTML's
>>> "allowed to use" algorithm with the current document. That algorithm
>>> <https://html.spec.whatwg.org/multipage/iframe-embed-object.html#allowed-to-use> is
>>> what calls Is feature enabled in document for origin
>>> <https://w3c.github.io/webappsec-feature-policy/#algo-is-feature-enabled>,
>>> and it always calls it with the document and the document's own origin, so
>>> the same-origin check should always be true (when called from HTML).
>>>
>>>
>>>>   The Is feature enabled in document for origin
>>>> <https://w3c.github.io/webappsec-feature-policy/#algo-is-feature-enabled>
>>>> alg, which does the combining of inherited, declared, and default policies,
>>>> appears to only be called from the former alg.
>>>>
>>>
>>> It's also called from Define an inherited policy for feature in
>>> container at origin
>>> <https://w3c.github.io/webappsec-feature-policy/#define-an-inherited-policy-for-feature-in-container-at-origin>,
>>> but more importantly, it's called from HTML: it's an exported algorithm
>>> that can be used as an entry point into Feature Policy from other specs.
>>>
>>>
>>>>   Also, if the *document* that is passed to the latter alg is the
>>>> top-level document, then the embedded document's declared policy (if any)
>>>> is not evaluated by the latter alg. And so this scenario would not work.  :(
>>>>
>>>
>>> Generally, the document passed to Is feature enabled in document for
>>> origin
>>> <https://w3c.github.io/webappsec-feature-policy/#algo-is-feature-enabled>, when
>>> used to answer "can a document use this feature?", is the document which is
>>> trying to use the feature, not the top-level doc.
>>>
>>>
>>>> If this is correct, then I am proposing that we make an exception for
>>>>> "payment" specifically to always require the "header policy" in the
>>>>> embedded iframe. This would be a change in the spec and, therefore,
>>>>> implementations, if I understand correctly.
>>>>>
>>>>
>>> We have discussed the idea that some features need an explicit opt-in
>>> from the embedded site in order to be *disabled*  -- this turns out to be
>>> important when disabling existing functionality; I don't know if anyone has
>>> considered requiring the same opt-in for *enabling* a feature. My belief
>>> has always been that if the embedding document is trusted to use the
>>> feature, then it should be able to delegate that to the documents that it
>>> embeds (if it trusts them as well). Are you suggesting that use of
>>> PaymentRequest should also require such an opt-in from the *embedded
>>> document*?
>>>
>>
>> Yep, that's what I am suggesting. Any HTTPS top-level context can use
>> PaymentRequest and PaymentHandler today, including https://evil.com. If
>> https://evil.com has an <iframe allow="payment" src="
>> https://good-site.com"></iframe>, then https://good-site.com will call
>> PaymentRequest and be none the wiser that it's not in complete control of
>> what HTML content the user is looking at. Do you think that Feature Policy
>> is the right tool to solve this problem?
>>
>>
>>> In any case, regardless whether Feature Policy is actually intended to
>>>> support the above feeble cross-origin example (this is not made clear in
>>>> the spec, ISTM), I am now guessing that the above example "header policy"
>>>> (i.e., Feature-Policy header field) ought to perhaps be:
>>>>
>>>> `Feature-Policy: payment example-embedding.foo;`
>>>>
>>>> ..and am wondering whether that would be a reasonable way for the
>>>> combination of the embedding and embedded parties to explicitly declare
>>>> that such cross-origin use of a feature(s) is allowed?  (this must have
>>>> already been discussed ?)
>>>>
>>>>
>>>>
>>>>
>>>>> #2: Would it be possible to disable these powerful APIs in all iframes
>>>>>>> that are not sandboxed? Cross origin iframes today have to look like this:
>>>>>>> <iframe allow="payments" src="https://payment-app.com/some.js"></iframe>,
>>>>>>> if the parent iframe wants to allow payments in the child iframe. Would it
>>>>>>> be kosher to require the tag to look like this: <iframe *sandbox*
>>>>>>> allow="payments" src="https://payment-app.com/some.js" ></iframe> ?
>>>>>>>
>>>>>>
>>>>>> Sandbox attribute is defined here
>>>>>> <https://html.spec.whatwg.org/multipage/iframe-embed-object.html#attr-iframe-sandbox>
>>>>>> .
>>>>>>
>>>>>> Given that definition, it seems that the sandbox attr does not match
>>>>>> your above use case. The sandbox attr is about protecting the embedding
>>>>>> webapp from the framed webapp/content (and not vice-versa), and also not
>>>>>> about controlling whether powerful features are enabled or not (the latter
>>>>>> is the province of Feature Policy).
>>>>>>
>>>>>> That said however, it may be overall reasonable standard best
>>>>>> practice for embedders to declare many iframes (in general) like so:
>>>>>>
>>>>>> <iframe sandbox="allow-same-origin allow-forms allow-scripts" src="
>>>>>> https://maps.example.com/embedded.html"></iframe>
>>>>>>
>>>>>> ..because it disables plugins and popups, thus reducing the risk of
>>>>>> the user being exposed to malware and other annoyances.
>>>>>>
>>>>>
>>>>> It feels like a payment sheet can fall into the category of "other
>>>>> annoyances."
>>>>>
>>>>
>>>> Possibly?
>>>>
>>>>
>>>>> I am proposing to change the spec to say: "if the cross-origin iframe
>>>>> does not have a sandbox attribute, then disable the payment APIs in that
>>>>> iframe." Does that sound reasonable?
>>>>>
>>>>
>>>> By spec, you're referring to the Payment Request spec?
>>>>
>>>> I remain uncertain that requiring the sandbox attr is appropriate.
>>>>
>>>>
>>>> However, the framed webapp is able to escape the sandbox relatively
>>>>>> easily. See examples and warnings in Sandbox attribute definition
>>>>>> <https://html.spec.whatwg.org/multipage/iframe-embed-object.html#attr-iframe-sandbox>
>>>>>> .
>>>>>>
>>>>>
>>>>> Is my reading of the spec correct that only iframes from the same
>>>>> origin as the embedder can escape sandbox?
>>>>>
>>>>
>>>> That seems to be implied?
>>>>
>>>> HTH,
>>>>
>>>> =JeffH
>>>>
>>>>
>>>>
>>>
Received on Thursday, 18 April 2019 19:00:06 UTC

This archive was generated by hypermail 2.3.1 : Thursday, 18 April 2019 19:00:07 UTC