How does Content-Security-Policy work with X-Frame-Options? - http

Does Content-Security-Policy ignore X-Frame-Options, returned by a server, or is X-Frame-Options still primary?
Assuming that I have:
a website http://a.com with X-Frame-Options: DENY
and a website http://b.com with Content-Security-Policy: frame-src a.com
will browser load this frame?
It is unclear.
On the one hand, http://a.com explicitly denies framing.
On the other hand, http://b.com explicitly allows framing for http://a.com.

The frame-src CSP directive (which is deprecated and replaced by child-src) determines what sources can be used in a frame on a page.
The X-Frame-Options response header, on the other hand, determines what other pages can use that page in an iframe.
In your case, http://a.com with X-Frame-Options: DENY indicates that no other page can use it in a frame. It does not matter what http://b.com has in its CSP -- no page can use http://a.com in a frame.
The place where X-Frame-Options intersects with CSP is via the frame-ancestors directive. From the CSP specificiation (emphasis mine):
This directive is similar to the X-Frame-Options header that several
user agents have implemented. The 'none' source expression is
roughly equivalent to that header’s DENY, 'self' to SAMEORIGIN,
and so on. The major difference is that many user agents implement
SAMEORIGIN such that it only matches against the top-level
document’s location. This directive checks each ancestor. If any
ancestor doesn’t match, the load is cancelled. [RFC7034]
The frame-ancestors directive obsoletes the X-Frame-Options header. If a resource has both policies, the frame-ancestors policy SHOULD be enforced and the X-Frame-Options policy SHOULD be ignored.
An older question indicated this did not work in Firefox at that time but hopefully things have changed now.
UPDATE April 2018:
Content Security Policy: Directive ‘child-src’ has been deprecated. Please use directive ‘worker-src’ to control workers, or directive ‘frame-src’ to control frames respectively.
Looks like child-src is now the deprecated one and frame-src is back.

None of your hypotheses are universally true.
Chrome ignores X-Frame-Options.
Safari 9 and below ignore CSP frame-ancestors.
Safari 10-12 respect the CSP frame-ancestors directive, but prioritize X-Frame-Options if both are specified.

The answer was found by testing in practice.
I have created two web-sites and reproduced the described situation.
It seems like X-Frame-Options is primary.
If target server denies framing, then client website cannot display this page in iframe whichever values of Content-Security-Policy are set.
However, I haven't found any confirmations in documentation.
Tested on Chrome 54 and IE 11.

Related

use X-Frame-Origin so that it's allowed on one site but nowhere else

How do you do this?
On example.com, I need to have it so an iFrame of example.com can load at subdomain.example.co.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
So it looks like the only two options are:
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
And the one I would have wanted
ALLOW-FROM uri
Is deprecated according to the linked MDN.
Then there's frame-source
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors
The HTTP Content-Security-Policy (CSP) frame-ancestors directive
specifies valid parents that may embed a page using , ,
, , or .
Setting this directive to 'none' is similar to X-Frame-Options: deny
(which is also supported in older browsers).
what does "valid parents" mean? Where specifically do I set this? It doesn't say what file on the server you need to change.
So if I say
Content-Security-Policy: frame-ancestors subdomain.example.co;
That will work? And if so, where on the server config do I do that?
frame-ancestors can only be set when Content-Security-Policy is set as a response header. It might be controlled in a .htaccess file, but it may also be set in other types of configuration, code, webserver or proxy, depending on your setup.
"Valid parents" would be the hosts that are allowed to frame your page. It could be multiple different pages and all the hosts in a chain of framing.
You can use X-Frame-Options ALLOW-FROM for IE when you also set frame-ancestors as frame-ancestors will cause the browser to ignore X-Frame-Options for most other browsers. If you set the value in code you can insert a value from a list of acceptable framers when the referrer matches.

Getting `HTTPS security is compromised` in ms-word addin on IE11

As the title states, I'm having issues with displaying my page in an iframe using x-frame-options: sameorigin
Looking at possible solutions, I came across x-frame-options: allow-from url, which made no difference. All of my resources are also served via https.
When using both x-frame-options: sameorigin and X-Frame-Options: allow-from url, the sameorigin header is disabled.
Also, documentation on x-frame-options found here:
# ALLOW-FROM uri
This is an obsolete directive that no longer works in modern browsers. Don't use it. In
supporting legacy browsers, a page can be displayed in a frame only on the specified origin
uri. Note that in the legacy Firefox implementation this still suffered from the same problem
as SAMEORIGIN did — it doesn't check the frame ancestors to see if they are in the same origin.
The Content-Security-Policy HTTP header has a frame-ancestors directive which you can use
instead.
I currently have the abovementioned frame-ancestors implemeted for other browsers' support, eg. Chrome, Safari, or Firefox, which is however unsupported by IE11. This is a security layer that I don't want to remove to avoid clickjacking.
Any advice?
As explained in the question, I found that when appending another x-frame-options header, the sameorigin was disabled.
So I modified the header slightly and found the following to work perfectly for IE11 and did not affect the other browsers:
res.set("X-Frame-Options", "SAMEORIGIN, ALLOW-FROM url");

Issue when Content-Security-Policy is present in both HTTP header and a meta tag [duplicate]

This question already has an answer here:
What is happening when I have two CSP (Content Security Policies) policies - header & meta?
(1 answer)
Closed 2 years ago.
We are working on a web project where the Content Security Policies are enforced via HTTP headers and via meta tags as well. There is a default set of properties which are a part of the HTTP header and each page specifies the additional policies by means of a meta tag in the document header.
One of the page in the project loads content inside an iframe. The Content-Security-Policy in the HTTP header for that page is
Content-Security-Policy: frame-src *;
and the page has the following meta tag in it's document header
<meta http-equiv="Content-Security-Policy" content="default-src none;"/>
It is mentioned in the MDN Web Docs that the fallback order is frame-src -> child-src -> default-src. In-spite of setting frame-src in the HTTP header, I get the following error message in the browser console (Tried on Google Chrome and Microsoft Edge):
Refused to frame '<url here>' because it violates the following Content Security Policy directive: "default-src none". Note that 'frame-src' was not explicitly set, so 'default-src' is used as a fallback.
Also,
Moving both the policies either to the HTTP header or to the
meta tag works as expected
The more general page above that frame-src one on Content Security Policy explains what you are seeing:
Multiple content security policies
CSP allows multiple policies being specified for a resource, including via the Content-Security-Policy header, the Content-Security-Policy-Report-Only header and a <meta> element.
You can use the Content-Security-Policy header more than once... Adding additional policies can only further restrict the capabilities of the protected resource.
So with multiple CSPs, it’s like all of them are in play and not, as you see to want, that they are combined into one combined policy. So in your example, you effectively have frame-src set to none (since you have a default-src and no specific override for frame-src) so opening it up later does not work.

Iframe Restritions

Is there any documentation that explains what you cannot do, to make an iframe unusable?
You cannot use facebook iframe because of x-frame-options is deny
Twitter you cannot use iframe because an ancestor violates the following content security policy directive:"frame-ancestors" self
Is there anywhere I can check what can and can't be set to accept an iframe
To my knowledge, there are two HTTP Headers that can be used to prevent a website from being loaded as an iframe on other websites:
X-Frame-Options
The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a <frame>, <iframe>, <embed> or <object>.
The possible values are:
deny
sameorigin
allow-fromuri
You can read more about what they each do on MDN.
Note that according to the specification, frame-ancestors takes precedence over X-Frame-Options:
The frame-ancestors directive obsoletes the X-Frame-Options header. If a resource has both policies, the frame-ancestors policy SHOULD be enforced and the X-Frame-Options policy SHOULD be ignored.
From the example you posted, it seems like Facebook has X-Frame-Options: deny as a response header, which prevents it from being loaded in an iframe from anywhere (in browsers that support this header).
Content-Security-Policy
Using either:
frame-ancestors which restricts what domains can embed this website in an iframe
The HTTP Content-Security-Policy (CSP) frame-ancestors directive specifies valid parents that may embed a page using <frame>, <iframe>, <object>, <embed>, or <applet>.
The main difference with X-Frame-Options is that
many user agents implement SAMEORIGIN such that it only matches against the top-level document’s location. This directive checks each ancestor. If any ancestor doesn’t match, the load is cancelled.
frame-src which restricts what domains this website can embed in an iframe
The HTTP Content-Security-Policy (CSP) frame-src directive specifies valid sources for nested browsing contexts loading using elements such as <frame> and <iframe>.
You can read more about frame-ancestors and frame-src on MDN.
From the example you posted, it seems like Twitter has Content-Security-Policy: frame-ancestors 'self', which means that that website can only be embedded on the same domain.

How to set X-Frame Options to ALLOW-FROM https://example.com and SAMEORIGIN on server

I have a requirement to set the X-Frame options on the server level to either:
X-Frame-Options: SAMEORIGIN
X-Frame-Options: ALLOW-FROM https://example.com/
Understand that X-Frame Options are mutually exclusive. See here.
However, my application requires framing in https://example.com and also from its SAMEORIGIN.
Please advise if there is a way around this while retainining my application's requirement to having allow framing on the same origin and be framed on 1 external site.
Or is this impossible?
In addition to only supporting one instance of the header, X-Frame-Options does not support any more than just one site, SAMEORIGIN or not.
You'll have to use Content-Security-Policy and frame-ancestors, which does support multiple origins, like so:
Content-Security-Policy: frame-ancestors 'self' https://example.com
A couple notes to bear in mind:
frame-ancestors obsoletes X-Frame-Options - meaning that if frame-ancestors is present and the browser supports it, it will override the behaviour of X-Frame-Options.
Internet Explorer and Edge do not currently support the frame-ancestors directive, according to MDN. This means they will fall back to X-Frame-Options. If you need to support multiple origins in IE or Edge, see this answer on SO with a workaround.
I had a similar requirement and i handled in global.asax. i checked from where the request is coming and based on that i changed the header value to either sameorigin or allow-from. hope that helps.

Resources