17

I tried to make a iframe with a drupal page but I received the following message:

Multiple "Refused to display (page adress) in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'."

Then, I tried to change the header of response in page controller using

$response->headers->set('X-Frame-Options', 'GOFORIT');

And I received the following message

Multiple 'X-Frame-Options' headers with conflicting values ('GOFORIT, SAMEORIGIN') encountered when loading '(page adress)'. Falling back to 'DENY'.

Drupal core puts the following code in all responses.

$response->headers->set('X-Frame-Options', 'SAMEORIGIN', FALSE);

So, how can I override the X-Frame-Options header for only this response to embed this page in other sites?

I'm using Drupal 8.0.0.

6 Answers 6

5

The X-Frame-Options header seems to have been added to Drupal 8 in order to prevent click-jacking: https://www.drupal.org/node/2514152

According to the notification above, in order to embed your Drupal site in other sites,

a new Response Subscriber needs to be added that has a higher priority as the current FinishResponseSubscriber (see core.services.yml) to overwrite or remove the header - depending on the use case

It also provides a code example:

<?php
    $path = $request->getPathInfo();

    if (strpos($path, '/fb-app/') === 0) {
      $request->headers->remove('X-Frame-Options');
    }
?>
29

Drupal 8 adds the response header X-Frame-Options: SAMEORIGIN to all pages. This prevents that the content is included in iframes on third party sites.

You can check this for example in the google image search that your content does not appear in the preview frame.

This feature was introduced in drupal 8 beta 13.

The change record

Core is now protected against click-jacking by default (X-Frame-Options: SAMEORIGIN)

is not correct in that the priority has to be higher, in fact it has to be lower. The code example changes the request but it has to change the response.

To provide a solution to the question here is the complete code including the yaml file to put this in the service container:

mymodule/src/EventSubscriber/RemoveXFrameOptionsSubscriber.php:

<?php

namespace Drupal\mymodule\EventSubscriber;

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

class RemoveXFrameOptionsSubscriber implements EventSubscriberInterface {

  public function RemoveXFrameOptions(FilterResponseEvent $event) {
    $response = $event->getResponse();
    $response->headers->remove('X-Frame-Options');
  }

  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = array('RemoveXFrameOptions', -10);
    return $events;
  }
}

mymodule/mymodule.services.yml:

services:
  remove_x_frame_options_subscriber:
    class: Drupal\mymodule\EventSubscriber\RemoveXFrameOptionsSubscriber
    tags:
      - { name: event_subscriber }
3
  • I'm using a custom field formatter to include Youtube iframes. How do I remove these X-Frame-Options for displaying YouTube iframe Player?
    – JayKandari
    Aug 3, 2016 at 8:16
  • This answer should be accepted now - it's well thought through and complete. Also thanks for the drop-in code, very helpful.
    – Storsey
    Jan 20, 2017 at 12:22
  • @4k4 life saver Jul 30, 2020 at 3:30
8

4k4 give great solution, but also may be

$response->headers->set('X-Frame-Options', 'ALLOW-FROM https://ALLOWED.SITE/');

better then

$response->headers->remove('X-Frame-Options');

2
  • 2
    Note that allow-from uri is deprecated and will no longer work on modern browsers. The only 2 options this header has at the moment is sameorigin or deny. X-Frame-Options MDN
    – Beebee
    Nov 12, 2019 at 11:52
  • And also note that if you use it anyway to support IE (in addition to frame-ancestors, as suggested by drupov), since unlike frame-ancestors it only seems to accept a single domain, this would break things like "remote video" embeds, which Drupal media renders with an outer iframe that's SAMEORIGIN. Jan 13, 2022 at 2:19
4

It is very simple to override the headers from .htaccess with a single statement

Header set X-FRAME-OPTIONS "ALLOWALL"

Alternativelly you can make it only apply on certain condition using if statement apache expressions

<If "%{QUERY_STRING} =~ /embed/">
    Header set X-FRAME-OPTIONS "ALLOWALL"
</If>

and then you can call your URL adding embed in your query string

https://domain.com/yoururl?param1=true&embed

For this to work you will need apache 2.4 or greater and headers module enabled. If not enabled you perhaps you can enable them with

sudo a2enmod headers
sudo service apache2 restart
4

There's now a downloadable module for Drupal 8: X-Frame-Options Configuration

This module can be used to set the x-frame-options header on your website with the appropriate directive. This might be useful when you want to include one of the pages of your site inside an iframe in another site.

The directives must be:

  1. DENY
  2. SAMEORIGIN
  3. ALLOW-FROM uri (Currently [2018-10-25] not accepted by chrome nor Safari). You will be allowed to configure which uri.
2

For newer browsers the ALLOW-FROM uri-settings would not work anymore, see "allow-from uri (obsolete)"-section in https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options

You need to add

$response->headers->set('Content-Security-Policy', 'frame-ancestors https://ALLOWED.SITE/'); in addition to what wakh.ru proposed:

$response->headers->set('X-Frame-Options', 'ALLOW-FROM https://ALLOWED.SITE/');

1
  • Note that you if you use "Remote video" Media on your site (which render with an outer same-origin iframe), you'll also want to account for that in Content-Security-Policy (e.g. frame-ancestors 'self' allowed.other.site with quotes required for 'self') since setting CSP seems to disregard/overrule X-Frame-Options set elsewhere, whether by core as SAMEORIGIN, or by customization as ALLOW-FROM (and since ALLOW-FROM also only accepts a single value, setting it to https://allowed.other.site also seems to break the video embeds in IE). Jan 13, 2022 at 1:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.