digitalist.global // December 20 2016

Remove X-Frame options and set Content-Security-Policy

Remove X-Frame options and set Content-Security-Policy

Out of the box Drupal 8 has the header of a page request set to X-Frame-Options: SAMEORIGIN, that means that many modern web browsers does not allow the site to be framed from another domain, mostly for security reasons. This is good in many cases, but some web browsers has problem with this, and X-Frame-Options is deprecated in favor of using Content-Security-Policy.

 

So why do you need a header like that? It is mainly for protecting a site for what is called Clickjacking

Also, for some cases you want you site to be framed into another, and doing that out of the box with Drupal 8 is not possible in most modern web browsers if you don’t alter the sites header in apache, nginx, varnish or in some other way. We are now going to look into doing in “some other way”, in this case with Drupal. I prefer using Drupal to control site headers because of the sites header is a part of the application.

This solution is based on this post on drupal.org.

Create a structure like this:

And here is the code

mycustom 
  ├── mycustom.info.yml 
  ├── mycustom.services.yml 
  └── src 
    └── EventSubscriber 
      └── MyCustomEventSubscriber.php 

mycustom.info.yml

 

 



name: My custom
type: module
description: Replacing X-frame-Options with Content-Security-Policy
core: 8.x
package: custom

mycustom.services.yml


services:
  shp_xframe_remove_event_subscriber:
    class: Drupal\mycustom\EventSubscriber\MyCustomEventSubscriber
    tags:
      - {name: event_subscriber}

src/EventSubscriber/MyCustomEventSubscriber.php


<?php
namespace Drupal\mycustom\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;

/**
 * Subscriber for changing header.
 */
class MyCustomEventSubscriber implements EventSubscriberInterface {

  /**
   * Remove X-Frame-Options, adding Content-Security-Policy.
   */
  public function setHeaderContentSecurityPolicy(FilterResponseEvent $event) {
    $response = $event--->getResponse();
    $response->headers->remove('X-Frame-Options');
    // Set the header, use FALSE to not replace it if it's set already.
    $response->headers->set('Content-Security-Policy', "frame-ancestors 'self' mysite.com *.mysite.com", FALSE);
  }

  /**
   * {@inheritdoc}
   */
  static public function getSubscribedEvents() {
    // Response: set header content for security policy.
    $events[KernelEvents::RESPONSE][] = ['setHeaderContentSecurityPolicy', -10];
    return $events;
  }

}

That is it.

 

More from digitalist.global