Search code examples
ruby-on-railsgoogle-chromeiframecontent-security-policyx-frame-options

ruby on rails allow embedding of your website in other sites using frame_ancestors content security policy or X-Frame-Options


I am trying to allow others embed pages from my rails app on many websites. I can get it to work in Chrome and Firefox using X-Frame-Options. Is there a content security policy that is equivalent response.headers['X-Frame-Options'] = "ALLOW-FROM *"

Here is the bit using X-Frame-Options

class PeopleController < ApplicationController
  def embed
    response.headers['X-Frame-Options'] = "ALLOW-FROM *"
    @company = People.new
  end
end

But does not work, when using content security policy in both Chrome and Google when i use content security policy

class PeopleController < ApplicationController

  content_security_policy do |p|
    p.frame_ancestors "self", "*"
  end

  def embed
    @company = People.new
  end
end

When using Content Security Policy, it throws this error:

Refused to frame 'http://localhost:3000/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors self".

and this is an example of the embed code:

  <iframe src="http://localhost:3000/people/embed"></iframe>

and this is another one I tried:

  <iframe src="/people/embed"></iframe>

Update

With content-security policy, this works only on Firefox:

content_security_policy do |p|
  p.frame_ancestors 'self', "*"
end

Solution

  • Modern Chrome and Firefox do not support ALLOW-FROM key in the X-Frame-Options header. You can publish X-Frame-Options: ALLOW-FROM ### or X-Frame-Options: ALLOW-FROM http://example.com - they restrict nothing, headers with ALLOW-FROM key be just ignore by browsers.

    If you wish to allow iframing for unlimited domains, it's easier not to publish X-Frame-Options header (and frame-ancestors directive) at all.

    If you have a counted set of allowed domains you can use CSP header with frame-ancestors domain1 domain2 ... domainN;.

    When using Content Security Policy, it throws this error: ... because an ancestor violates the following Content Security Policy directive: "frame-ancestors self"

    This error means that you really published frame-ancestors 'self', not frame-ancestors 'self' * as expected.
    Maybe you published two different CSP headers at the same time, maybe you have error in code. You can check what CSP header you actually got in browser.

    Note 1: 'self' token should be a single-quoted - use "'self'" string in code.

    Note 2: 'self' token commonly covers standard ports 80/443 only, it's not cover http://localhost:3000 (it's browser's depend). An asterisk * does cover any port numbers.