X-FRAME-OPTIONS is a web header that can be used to allow or deny a page to be iframed. This is very important when protecting against clickjacking attempts. Using this header you can ensure that your content is not rendered when placed inside an IFrame, or only rendered under certain conditions (Like when you are framing yourself).
A common alternative to protect against clickjacking is to use javascript code to “break” iframes when your website is placed in them. This works for the most part but will obviously fail if the user does not have JS enabled, or (more common than you think), you forget to load the JS file on a particular page.
X-Frame-Options Settings
Your options when setting the header as as follows.
X-FRAME-OPTIONS : DENY
The page cannot be put in a frame no matter who it is (Including the site framing itself). If you don’t use frames on your own site then this is a good catch all.
X-FRAME-OPTIONS : SAMEORIGIN
The page can be framed as long as the domain framing it is the same. This is good if you are using frames yourself.
X-FRAME-OPTIONS : ALLOW-FROM https://myotherdomain.com
The page can be framed by the specified domains. Good if you have two sites with one framing the other.
Note that Allow-From is only supported in Firefox and IE. Chrome and Safari have both said that they will not support it and instead implement “Content-Security-Policy”, an alternative way to prevent clickjacking (And the subject of a future post!). Because of that it is not recommended you use this setting, stick with DENY or SAMEORIGIN.
Setting X-Frame-Options At The Code Level
Adding X-FRAME-OPTIONS to your .NET Core app is very simple. In your Configure method in your startup.cs, you need to add a custom middleware like so :
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.Use(async (context, next) => { context.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN"); await next(); }); app.UseMvc(); }
And that’s all! Now every request that runs through your ASP.NET Core app will be protected.
Setting X-Frame-Options At The Server Level
You (or your dev ops team) may prefer to configure headers at the server level. In that case below are the various ways to add X-FRAME-OPTIONS to your web server so every request gains the header.
Setting X-FRAME-OPTIONS in IIS
The best way to do this if you are just using IIS to forward requests to Kestrel (Or even if this is actually being hosted in IIS), is to do this in IIS Manager.
- Open IIS Manager and on the left hand tree, left click the site you would like to manage.
- Doubleclick the “HTTP Response Headers” icon.
- Right click the header list and select “Add”
- For the “name” write “X-FRAME-OPTIONS” and for the value write in your desired option e.g. “SAME-ORIGIN”.
Setting X-FRAME-OPTIONS in Apache
In your httpd.conf file you need to append the following line :
Header always append X-Frame-Options SAMEORIGIN
Setting X-FRAME-OPTIONS in htaccess
If you are using shared hosting you may only have access to an HTAccess file. Or you may prefer to use HTAccess to manage redirects, headers etc anyway. If that’s the case you need to add the following to your .htaccess file.
Header append X-FRAME-OPTIONS "SAMEORIGIN"
Setting X-FRAME-OPTIONS in NGINX
In nginix.conf add the following line (And restart the nginx service afterwards).
add_header X-Frame-Options "SAMEORIGIN";
Thanks for this. Its very helpful, however I had to use the value SAMEORIGIN not SAME-ORIGIN for the “Setting X-FRAME-OPTIONS in IIS”. The browser doesnt seem to recognise “SAME-ORIGIN” as it was still allowing pages to be iframed from external sites. Once I changed the value to SAMEORIGIN it works.
Cheers
Regarding the line:
await next();
Does this deliberately need to run on the original thread’s context?
Were we to write this in full, would we have:
await next().ConfigureAwait(false);
or
await next().ConfigureAwait(true);
Just a reminder this middleware should go above both use.mvc(), as shown above, and any endpoint declarations.
Thanks for the quick and easy article.