I am trying to display iframe from x.example.com on a web page hosted at y.example.com
Here are the settings that I have done so for
Tomcat:
<filter>
<filter-name>ClickJackFilterEnabled</filter-name>
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
<init-param>
<param-name>antiClickJackingEnabled</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ClickJackFilterEnabled</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Spring Security:
httpResponse.setHeader("Content-Security-Policy", "default-src 'self' *.example.com; style-src 'self' *.googleapis.com *.amazonaws.com 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; child-src 'self' *.example.com; font-src *;img-src 'self' *.amazonaws.com");
httpResponse.setHeader("Access-Control-Allow-Origin", "http://*.example.com");
When I open the page with embedded iframs, I am still getting this error:
Refused to display 'http://x.example.com/' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.
Uncaught SecurityError: Sandbox access violation: Blocked a frame at "http://y.example.com" from accessing a frame at "http://x.example.com". The frame being accessed is sandboxed and lacks the "allow-same-origin" flag.
When I checked the headers using curl, the header X-Frame-Options does not exist
This the the output of curl
* Rebuilt URL to: y.example.com/
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 127.0.0.1...
* Connected to y.example.com (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: y.example.com
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Application-Context: application:dev:8080
< Content-Security-Policy: default-src 'self' *.example.com; style-src 'self' *.googleapis.com *.amazonaws.com 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; child-src 'self' *.example.com; font-src *;img-src 'self' *.amazonaws.com
< Access-Control-Allow-Origin: http://*.example.com
< Content-Type: text/html;charset=UTF-8
< Content-Language: en-IN
< Transfer-Encoding: chunked
< Date: Wed, 20 Jul 2016 13:21:57 GMT
<
{ [8200 bytes data]
What am I missing?
UPDATE:
I tried to set
document.domain = "example.com"
On both the web pages, I am still getting the error
Refused to display 'http://x.example.com/' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'
When I type
document.domain
in the javascript console, I am getting
"example.com"
On both the web pages. So the origin is same for both the pages.
Finally I was able solve the issue. The problem is probably with how browsers deal with X-Frame-Options header.
The concept behind setting
document.domain = "example.com"
is to make the origin same for both the web pages. Browsers allow setting origin to a parent domain, so a page at a.x.example.com can set value of document.domain to x.example.com or to example.com
Now, even after setting document.domain to example.com, I was getting the error
Refused to display 'http://x.example.com/' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'
When I removed the X-Frame-Options header altogether, using
http.headers().frameOptions().disable();
In securityConfiguration.java, it worked!
I don't know the reason why browsers didn't honour the document.domain setting. Couldn't find anything on this in mozilla documentation, or anywhere else. Hope this helps someone.