Problem/Motivation
Imagine a scenario, where the main website is served at https://example.com, and the iFrame domain options is set to an alias; https://oembed.example.com
This way when media on a page is viewed, the markup on https://example.com would be something like:
<iframe src="https://oembed.example.com/media/oembed?url=https%3A//youtu.be/Dc3LpT69crc&max_width=0&max_height=0&hash=J3reigEh1oul-MNqUBBvVbfHUo1eI54gZryZJT22g1E" frameborder="0" allowtransparency width="480" height="270" class="media-oembed-content"></iframe>
Steps to reproduce
Out-of the box, this fails with an error:
Refused to display 'https://oembed.example.com/media/oembed?url=https%3A//youtu.be/Dc3LpT69c...' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
Proposed resolution
Unless an appropriate X-Frame-Options header is set, the iframe content will not load.
Should this be an optional setting, addition to iFrame domain in Media settings > Security?
$form['security']['x_frame_options'] = [
'#type' => 'checkbox',
'#title' => $this->t('Set HTTP header: X-Frame-Options: allow-from {IFRAME_DOMAIN}'),
'#default_value' => $this->config('media.settings')->get('x_frame_options'),
'#description' => $this->t('If the content served from iFrame domain is not displayed try enabling this option.'),
'#states' => [
'invisible' => [
':input[name="iframe_domain"]' => ['empty' => TRUE],
],
],
];
Then set the HTTP header in an EventSubscriber:
public function onKernelResponse(FilterResponseEvent $event) {
$iframe_domain = $this->config->get('iframe_domain', '');
$x_frame_options = $this->config->get('x_frame_options', 0);
if ($iframe_domain !== '' && (bool) $x_frame_options) {
$response = $event->getResponse();
$response->headers->set('X-Frame-Options', "allow-from ${iframe_domain}");
}
}
Remaining tasks
None
User interface changes
None
Introduced terminology
None
API changes
None
Data model changes
None
Release notes snippet
None
Issue fork drupal-3075685
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
osmanTurns out setting
X-Frame-Optionsalone doesn't resolve the issue by itself. It still seems to require Content-Security-Policy header to be set.Most importantly,
X-Frame-Optionsis deprecated in favor of Content-Security-Policy.Seems like though, any solution needs to use a combination of these headers to make it work.
Since every project's solution will have to be custom defined, i'm closing this issue.
Comment #3
a8w4This is absolutely not satisfactory - you're setting the site-builder up for failure. This configuration will - as it momentarily is - never work!
How can this be "working as designed"? At the very least there should be an informational text, that there is a problem and how to solve it. A minimal solution would be to set at least the Header
Content-Security-Policy: frame-ancestors <source>with the iFrame-Domain as<source>. I've found out, that this works with the X-Frame-Options header untouched!Comment #4
a8w4Comment #5
maosmurf commentedI agree: the current default setup does not allow embeding oembed iframes from another subdomain.
I can also confirm that we could solve the problem without touching
X-Frame-Options(found in\Drupal\Core\EventSubscriber\FinishResponseSubscriber::onRespond)In order to do so, we installed drupal/csp using default settings + adding frame-ancestors to regular URL (not the oembed one):
EDIT: for sake of completeness, we also had to resolve the problem of unauthenticated access (login not passed down to oembed iframe). A simplified solution could look like this:
Comment #6
phenaproximaBumping the priority here, since I think this is a major bug and prevents oEmbed stuff from working properly.
I'm also tagging this for security review because I'd like a member of security team to confirm that there isn't any harm in Media setting this header. Or, if there is potential danger, what we might do to mitigate it.
Comment #7
pameeela commentedComment #8
tboggia commentedIf anyone else is arriving here because YouTube embeds are giving this error, replace
/watch?v=with/embed/in your iframe src (h/t this stackoverflow about the error).Comment #9
duaelfrHi there!
I'm facing this issue too. I enabled the "iFrame domain" setting due to the worrying message in the form.
I installed the CSP module and configured the frame-ancestors setting with the main domain.
I think either the Core should set the appropriate headers or drop this setting to leave it to some contrib modules like CDN.
Comment #14
newaytech commentedFurther discussion here - thanks for the CSP tip!
Comment #18
plachWorking on this.
Comment #19
plachComment #20
smustgrave commentedCan the issue summary be updated please to match standard issue template.
Comment #22
moshe weitzman commentedUpdated the MR and now using the Issue summary template.
May I gently suggest that when we ask to use the issue summary template, we don't also switch to Needs Work just for that reason. Its more important to fix a bug than it is to use the official template.
Comment #23
smustgrave commentedWill disagree if the ticket isn’t correct it can’t move forward and won’t be accepted by committers. Thus delaying it further
Comment #24
smustgrave commentedSo brought this up in #security-team channel and was recommended by @longwave to postpone this one as the iframe domain feature is planned to be removed from Drupal.
Believe #2965979: Validate alternate domain for oEmbed iFrame is the correct ticket.