Re: characterizing framing security needs for webappsec consideration

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 Wednesday, 17 April 2019 14:02:11 UTC