Intent to Ship: Changes to `X-Frame-Options: SAMEORIGIN`

1,205 views
Skip to first unread message

Mike West

unread,
May 12, 2017, 6:07:20 AM5/12/17
to blink-dev

Contact emails

mk...@chromium.org


Spec

https://tools.ietf.org/html/rfc7034


Summary

Currently, XFO performs a same origin check only against the top-level frame in a document's ancestor chain. As lcamtuf notes in [1], "Any site that allows a rogue ad to be displayed in an IFRAME; or that frames third-party content for other reasons (e.g., iGoogle, Image Search results, Facebook gadgets), is effectively not protected, because the framed content from evil.com can load and arbitrarily decorate any page in the same origin as the top-level window, and entice the user to interact with it."

Back in the misty darkness of 2013, we tried to change this behavior to check each of a document's ancestors. But we broke things, so we reverted it.


Is this feature supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?

Yes.


Debuggability

No change to XFO's current display in devtools (it shows up as a cancelled request, and is flagged with a console warning).


Interoperability and Compatibility Risk

https://www.chromestatus.com/metrics/feature/timeline/popularity/60 is hovering around 0%. This does not seem to pose a large interoperability risk anymore.


Edge: No signals

Firefox: Public support (several years ago in https://bugzilla.mozilla.org/show_bug.cgi?id=725490. I expect they'd follow us if we can successfully change this behavior.)

Safari: No signals

Web developers: Positive (people are generally surprised at SAMEORIGIN's behavior when we explain it to them. See https://speakerdeck.com/filedescriptor/exploiting-the-unexploitable-with-lesser-known-browser-tricks?slide=9 for example)


Please include links where possible.


Is this feature fully tested by web-platform-tests?

We have plenty of layout tests, but haven't yet upstreamed them to WPT. I'll work on that as part of this change.


OWP launch tracking bug

https://bugs.chromium.org/p/chromium/issues/detail?id=250309


Entry on the feature dashboard

https://www.chromestatus.com/feature/4678102647046144


Thanks!



-mike

Jochen Eisinger

unread,
May 12, 2017, 6:08:45 AM5/12/17
to Mike West, blink-dev
lgtm1

PhistucK

unread,
May 12, 2017, 2:28:45 PM5/12/17
to Jochen Eisinger, Mike West, blink-dev
Can you poke the other vendors for signals (preferably in a GitHub issue)?


PhistucK

lgtm1
--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+unsubscribe@chromium.org.

Rick Byers

unread,
May 12, 2017, 3:24:06 PM5/12/17
to PhistucK, Jochen Eisinger, Mike West, blink-dev
LGTM2 assuming WPT tests for this are upstreamed when/before it lands in Chrome.

Rick Byers

unread,
May 12, 2017, 3:41:59 PM5/12/17
to PhistucK, Jochen Eisinger, Mike West, blink-dev
Whoa wait a second here.  The XFrameOptions UseCounters are no longer in our code - usage has declined because it's only versions of Chrome prior to Chrome 57 which are reporting it!  I tried finding the CL that removed it but git blame was giving me some trouble.  Mike, I think you're going to have to restore the UseCounter (or do some other form of compat analysis) in order to evaluate the compat risk here.

Rick

PhistucK

unread,
May 12, 2017, 3:45:51 PM5/12/17
to Rick Byers, Jochen Eisinger, Mike West, blink-dev
Can ChromeStatus reflect the existence of the UseCounter in the code somehow (or maybe remove it from the list if it does not exist in the code)?


PhistucK

Alex Moshchuk

unread,
May 12, 2017, 9:12:55 PM5/12/17
to Rick Byers, PhistucK, Jochen Eisinger, Mike West, blink-dev
I think these UseCounters were removed as part of moving XFO enforcement to the browser process in https://codereview.chromium.org/2488743003.  They were replaced with different UMA metrics, so hopefully those can be used for compat analysis in M57+.

Alex

Mike West

unread,
May 13, 2017, 12:53:06 AM5/13/17
to Alex Moshchuk, Rick Byers, PhistucK, Jochen Eisinger, blink-dev
Ugh. That's embarrassing. Alex is right, this moved to the browser a while back, and I even reviewed the patch. :(

The new histogram is `Security.XFrameOptions`, and shows that over the past 28 days, 0.00426% of framed navigations fell into this category. That doesn't precisely map to the UseCounter (as the total page counts there would include the top-level navigations, and this counter isn't deduped per page), but looks like it's consistent with the numbers we have there up through M57.


-mike

Mike West

unread,
May 15, 2017, 3:31:40 AM5/15/17
to Alex Moshchuk, Rick Byers, PhistucK, Jochen Eisinger, blink-dev
HTTPArchive shows 22 pages affected. I ran through each of them and see a few trends:

I'll poke at Tumblr folks, I suppose. If this is widely used, they could serve the photos frame with `Content-Security-Policy: 'self' http://scmplayer.net` as a better-targeted solution.

-mike

Mike West

unread,
May 16, 2017, 7:11:58 AM5/16/17
to Alex Moshchuk, Rick Byers, PhistucK, Jochen Eisinger, blink-dev
On Mon, May 15, 2017 at 9:31 AM, Mike West <mk...@chromium.org> wrote:
HTTPArchive shows 22 pages affected. I ran through each of them and see a few trends:

I'll poke at Tumblr folks, I suppose. If this is widely used, they could serve the photos frame with `Content-Security-Policy: 'self' http://scmplayer.net` as a better-targeted solution.

I talked to a friendly person on Tumblr's security team yesterday; they're investigating whether they need XFO on the particular resource in question at all. If they do, `frame-ancestors` (or an `ancestorOrigins` check) seems like a good workaround that they sound willing to undertake. If not, they'll remove it.

Either way, I think the user-facing impact of this change should be minimized. WDYT?

-mike

Rick Byers

unread,
May 16, 2017, 1:36:53 PM5/16/17
to Mike West, Alex Moshchuk, PhistucK, Jochen Eisinger, blink-dev
Ok, thanks for the analysis Mike.  I agree we should give this another go without waiting for new UMA data (but be prepared to revert if the new UseCounter and/or feedback indicates non-trivial breakage other than Tumblr).  So my LGTM2 still stands.

Rick Byers

unread,
May 16, 2017, 1:41:20 PM5/16/17
to PhistucK, Jochen Eisinger, Mike West, blink-dev
Yes, I think we can fix this by reporting data only for the "dominant" version on each day (a variation of what I was already planning on doing eventually to avoid confusion with non-stable channels).  Tracked here.

Chris Harrelson

unread,
May 16, 2017, 8:21:50 PM5/16/17
to Rick Byers, PhistucK, Jochen Eisinger, Mike West, blink-dev

tcro...@liquidweb.com

unread,
Jul 13, 2017, 11:07:48 AM7/13/17
to blink-dev
Not sure if I’m supposed to reply here, or on https://bugs.chromium.org/p/chromium/issues/detail?id=250309#, but I thought I’d chime in as this change has unfortunate implications for an app I maintain.

For what it's worth, this change breaks authorize.net's hosted form iframe/lightbox implementation (https://developer.authorize.net/api/reference/features/accept_hosted.html#Transaction_Response). I wouldn't find this change so problematic if I could actually use CSP frame-ancestors (https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Limitations) or X-Frame-Options ALLOW-FROM (https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Limitations_2). Is there a cross-browser friendly way to allow the iframe communicator (and only the iframe communicator) from an app to be framed by only authorize.net? I can’t see a way outside of nginx hacks, so I’m not sure how best to move forward here. Any help would be much appreciated.

Side note: I’ve looked over this forum and the issue tracker... but I can’t find any information on when this change is supposed to ship. Is there a version of Chrome that this change is slated for?

Thanks!

PhistucK

unread,
Jul 13, 2017, 1:43:21 PM7/13/17
to tcro...@liquidweb.com, blink-dev
Can you add the header according to the referrer?


PhistucK

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+unsubscribe@chromium.org.

tcro...@liquidweb.com

unread,
Jul 13, 2017, 1:53:52 PM7/13/17
to blink-dev, tcro...@liquidweb.com
That is what I ended up doing via nginx. Check the referrer, check the location, remove the previously defaulted SAMEORIGIN header by setting the value empty. So perhaps that _is_ the best way to move forward :-/


PhistucK

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

PhistucK

unread,
Jul 13, 2017, 2:05:45 PM7/13/17
to tcro...@liquidweb.com, blink-dev
Wait, I am not sure I understand how this breaks your application. Sounds like this is the behavior that you desire, rather than the behavior that breaks you. I mean, sounds like you want SAMEORIGIN to really mean SAMEORIGIN of the frame that frames you, not of the top level frame, which is what this intent wants to do (unless I am mistaken about the intent or about your need).


PhistucK

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+unsubscribe@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/0c8a5fcd-403f-4c42-8db4-b6a6c5447f2b%40chromium.org.

tcro...@liquidweb.com

unread,
Jul 13, 2017, 4:16:29 PM7/13/17
to blink-dev, tcro...@liquidweb.com
With the app's header set to SAMEORIGIN today in Chrome, using authorize.net's hosted payment form iframe/lightbox implementation (https://developer.authorize.net/api/reference/features/accept_hosted.html#Transaction_Response), the iFrameCommunicator loads and the payment form works. In Chrome beta it does not.

See authorize.net's documentation for more details but tl;dr, in our app we load authorize.net hosted form in an iframe and in the authorize.net iframe they frame our communicator. It works because SAMEORIGIN currently does not look at all ancestors. Thus, without taking some action before this Chrome beta change releases, the app's checkout will break. 

I have made the nginx changes and they are currently being tested in a development environment on the assumption that this will release. I felt it was worth mentioning that this change does break authorize.net's payment form. They're not Paypal and not all websites use their payment form in an iframe surely and those that do may not be setting XFO to SAMEORIGIN. Still, ours may not be the only app effected.



PhistucK

Mike West

unread,
Jul 14, 2017, 7:56:57 AM7/14/17
to tcro...@liquidweb.com, blink-dev
On Thu, Jul 13, 2017 at 5:07 PM, <tcro...@liquidweb.com> wrote:
For what it's worth, this change breaks authorize.net's hosted form iframe/lightbox implementation (https://developer.authorize.net/api/reference/features/accept_hosted.html#Transaction_Response).

I'm sorry to hear that! Thanks for reporting the issue.
 
I wouldn't find this change so problematic if I could actually use CSP frame-ancestors (https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Limitations) or X-Frame-Options ALLOW-FROM (https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Limitations_2). Is there a cross-browser friendly way to allow the iframe communicator (and only the iframe communicator) from an app to be framed by only authorize.net? I can’t see a way outside of nginx hacks, so I’m not sure how best to move forward here. Any help would be much appreciated.

It sounds like you should be able to use `frame-ancestors` today. That is, if you serve a response with `X-Frame-Options: SAMEORIGIN` and `Content-Security-Policy: frame-ancestors 'self' https://origin1.com`, Chrome should ignore the XFO header in favor of the CSP header (as per https://w3c.github.io/webappsec-csp/#frame-ancestors-and-frame-options, and the tests at https://github.com/w3c/web-platform-tests/blob/master/content-security-policy/frame-ancestors/frame-ancestors-overrides-xfo.html). Is that override not happening?
 
Side note: I’ve looked over this forum and the issue tracker... but I can’t find any information on when this change is supposed to ship. Is there a version of Chrome that this change is slated for?

This change should be shipping in Chrome 60, which is in beta right now. I've updated the tracker accordingly, sorry I let it get out of date!

-mike

shobhit....@gmail.com

unread,
Jul 20, 2017, 2:39:55 PM7/20/17
to blink-dev, tcro...@liquidweb.com
Just want to check if someone can confirm if   `Content-Security-Policy: frame-ancestors 'self' https://origin1.com` is solving this problem.

Shobhit

he...@bythepixel.com

unread,
Aug 8, 2017, 4:53:51 PM8/8/17
to blink-dev
We have ran into this problem on production as well. It is unfortunate that this hit stable channel and breaks the Authorize.net's hosted iframe form implementation. We did get this working by using the `Content-Security-Policy` equal to `frame-ancestors 'self' *.authorize.net`. This should be a header you can easily set from your web server configuration.

mailb...@gmail.com

unread,
Sep 14, 2017, 10:05:42 AM9/14/17
to blink-dev, tcro...@liquidweb.com
This change also appears to break Chase Paymentech's Hosted Pay Page implementation: https://www.chasepaymentech.com/hosted_pay_page.html

Mike West

unread,
Sep 14, 2017, 11:10:28 AM9/14/17
to mailb...@gmail.com
-others to BCC

Thanks for the report! Can you point me to a page that this breaks? I don't see a demo on the link you provided.

-mike

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.

mailb...@gmail.com

unread,
Sep 14, 2017, 2:00:23 PM9/14/17
to blink-dev, mailb...@gmail.com, mk...@google.com
Hello Mike,

Unfortunately I do not have permission to share the website with you as I've built it on behalf of my employer. However I can confirm that adding this HTTP header solved the issue:

Content-Security-Policy: frame-ancestors 'self' www.chasepaymentechhostedpay-var.com www.chasepaymentechhostedpay.com


Thanks,

Nathan

Reply all
Reply to author
Forward
0 new messages