krakenjs / zoid

Cross domain components
Apache License 2.0
2.02k stars 248 forks source link

How does xcomponent account for Xframe option deny when building the iframe and sharing cross domain? #58

Closed mmairs9-zz closed 7 years ago

bluepnume commented 7 years ago

Can you clarify the question? Do you have control over the iframe, and if so why set x-frame-options: deny?

xcomponent specifically depends on being able to render iframes, and x-frame-options: deny specifically blocks iframes. So the two are pretty incompatible I'd say. :)

mmairs9-zz commented 7 years ago

The component we are wanting to reuse is authenticated via sso with adfs. Which in turn is putting the xframe option of deny within the frame. Wasn't sure if xcomponent was able to bypass this Somehow, having the iframe appear as if it's on same origin or some magic like that.

With having your components available cross domain what approach do u have to protect against click jacking if you aren't setting any xframe option?

bluepnume commented 7 years ago

So, all of the usual rules and drawbacks for iframes also apply with xcomponent, from a security perspective. xcomponent makes it easy to render and iframe and pass data down and up securely, but you still need to treat that iframe with all of the usual safeguards as a regular iframe.

If you only want to allow the iframe to be rendered on certain domains, you should make use of x-frame-options: sameorigin or x-frame-options: allow-from foo.com, etc. Otherwise you're implicitly saying "any site/domain may render this component", which is left as an option for you. So it's possible to create a component that anyone can use, or only a subset of whitelisted domains, depending on your needs, security concerns, etc.

xcomponent is purely client side and can't bypass x-frame-options, and it would be a bad thing if it could. That way you can be sure x-frame-options has the final say as to where a component/iframe can be rendered.

As far as click-jacking goes, you have the same level of protection as with any other iframe, whether or not it's rendered using xcomponent, no more and no less. So it really depends on the experience inside the iframe -- if there are form fields you have to fill out, click jacking is not going to be easy. If your experience is just a single click, click jacking is a lot easier. I'd love to bake some extra protection into xcomponent, but at the end of the day, it's a client-side library, so there's only so much it can do. Very open to suggestions though.

xcomponent also offers rendering to a popup window, with the exact same api. There's an example of this in the demo folder. With popups, there's no click-jacking risk.

mmairs9-zz commented 7 years ago

Thanks for the well explained answer. The allow from xframe option only allows one domain which is a shame as we want to share it across multiple internal sites.

bluepnume commented 7 years ago

Actually, if you have a whitelist of domains, you can just pass along the domain in the url.

On the client:

var domain = window.location.protocol + '//' + window.location.host;

var MyComponent = xcomponent.create({
    url: 'https://www.mysite.com/mycomponent?domain=' + domain
});

On the server:

var XFRAME_WHITELIST = [ 'https://x.com', 'https://y.com', 'https://z.com' ];

if (XFRAME_WHITELIST.indexOf(req.query.domain) !== -1) {
    res.setHeader('X-FRAME-OPTIONS', 'ALLOW-FROM ' + req.query.domain);
}

That way you can whitelist as many domains as you like to be rendered into an iframe.

bluepnume commented 7 years ago

Closing this issue -- please let me know if there's anything else I can help with, thanks!