Somil Bhandari
Somil Bhandari

Reputation: 183

enable subdomain iframe access

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.

Upvotes: 1

Views: 5052

Answers (2)

Somil Bhandari
Somil Bhandari

Reputation: 183

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.

Upvotes: 1

Mark Olsson
Mark Olsson

Reputation: 320

x.example.com is the one sending the SAMEORIGIN header. y.example.com can't override this, because then there would no way to block an iframe include. A site must grant permission (by lack of an origin policy or list of sites with permission) to other sites to include its contents.

Check the headers coming from x.example.com and you should see the policy actually blocking the iframe.

Upvotes: 1

Related Questions