11

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.

4

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');
    }
?>
| improve this answer | |
22

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 }
| improve this answer | |
  • 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 '16 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 '17 at 12:22
6

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');

| improve this answer | |
  • 1
    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 '19 at 11:52
2

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
| improve this answer | |
1

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.
| improve this answer | |
0

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/');

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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