question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Safe to disable X-FRAME-OPTIONS for Content Security Policy?

See original GitHub issue

Is it safe to disable frameguard and use contentSecurityPolicy instead? For some reason, Chrome is prioritizing X-FRAME-OPTIONS, and it doesn’t have a way to allow an entire domain, only a specific URL.

This is the solution I came up with:

helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
    },
  },
  frameguard: false,
})

Since I have an iframe I’m using for authentication on a variety of same-domain (but not same-subdomain) sites, I’m looking for a way of replacing frameguard with contentSecurityPolicy so I can set frameSrc: ["'self'", '*.example.com']

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:28 (13 by maintainers)

github_iconTop GitHub Comments

17reactions
EvanHahncommented, Jul 13, 2018

Okay—thanks!

tl;dr, it’s safe to disable X-Frame-Options as long as you also specify the frame-ancestors Content Security Policy directive, but be wary of the latter’s browser support.

At the end of the day, you have two goals:

  1. Your outer pages should only allow auth-example-iframe.com to be put in an iframe.
  2. Your iframe should only be embedded by foo.example.com and boo.example.com.

(Obviously these are example domains, and I’m only assuming you have two outer domains, but this should be easy to map to your actual setup.)

These two goals are largely unrelated in terms of implementation—you’ll need to set two different policies in order to achieve this.

Goal 1: only allow the auth iframe

Your outer pages will want a Content Security Policy that only allows auth-example-iframe.com to be framed. You can achieve this with the frame-src directive.

Here’s what that might look like with Helmet:

app.use(helmet.contentSecurityPolicy({
  directives: {
    // ...
    frameSrc: ['https://*.auth-example-iframe.com']
  }
}))

The more specific you can make that URL, the tighter your policy will be (which is generally a good thing). For example, if you know the exact URL, you can specify that:

frameSrc: ['https://auth.auth-example-iframe.com/auth']

The X-Frame-Options header (helmet.frameguard) is irrelevant here. I’d recommend that you include it so that your outer pages don’t get put in iframes, but that’s a separate issue.

Goal 2: only allow the iframe to be in some places

The iframe should only be embedded on foo.example.com and boo.example.com, let’s say. You can achieve this with the frame-ancestors directive.

Because you want multiple different domains, the X-Frame-Options header should be removed, as you’ve done.

Here’s what that might look like in code:

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      frameAncestors: [
        'https://foo.example.com',
        'https://boo.example.com'
      ]
    }
  },
  frameguard: false
}))

If you wish to allow any subdomain of example.com:

frameAncestors: ['https://*.auth-example-iframe.com']

Browser support might be a concern here. Content Security Policy Level 2 deprecates frame-src and introduces child-src and frame-ancestors. Not all browsers support CSP 2.

Does that help?

4reactions
matusferkocommented, Sep 19, 2018

app.use(helmet({frameguard: false})) executes framequard middleware with option SAMEORIGIN. There is no way currently to configure helmet to avoid X-Frame-Options header. Am I missing something?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Current best practices to restrict framing in the browser
The recommended best practice is to deny framing by setting both the X-Frame-Options header and the Content-Security-Policy header; Unless you ...
Read more >
X-Frame-Options - HTTP - MDN Web Docs
This is an obsolete directive that no longer works in modern browsers. (Using it will give the same behavior as omitting the header.)...
Read more >
Clickjacking Defense - OWASP Cheat Sheet Series
Preventing the browser from loading the page in frame using the X-Frame-Options or Content Security Policy (frame-ancestors) HTTP headers.
Read more >
Securely Bypassing X-Frame-Options or ... - Usama Ejaz
This is because of the content security policy implemented by the host page. To bypass this, you will need to modify the page's...
Read more >
How to Remove X-Frame-Options SAMEORIGIN from ...
If you are not 100% sure you should remove the X-Frame-Options: SAMEORIGIN header, do not remove it. The header adds a layer of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found