Skip to content

Commit

Permalink
SA-CORE-2021-006 by azinck, seanB, effulgentsia, marcoscano, larowlan…
Browse files Browse the repository at this point in the history
…, phenaproxima, xjm, mcdruid, drumm, briantschu
  • Loading branch information
xjm committed Sep 14, 2021
1 parent e536176 commit 6b60b88
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 24 deletions.
3 changes: 3 additions & 0 deletions modules/media/js/plugins/drupalmedia/plugin.es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,9 @@
uuid: this.data.attributes['data-entity-uuid'],
},
dataType: 'html',
headers: {
'X-Drupal-MediaPreview-CSRF-Token': editor.config.drupalMedia_previewCsrfToken,
},
success: (previewHtml, textStatus, jqXhr) => {
this.element.setHtml(previewHtml);
this.setData(
Expand Down
3 changes: 3 additions & 0 deletions modules/media/js/plugins/drupalmedia/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@
uuid: this.data.attributes['data-entity-uuid']
},
dataType: 'html',
headers: {
'X-Drupal-MediaPreview-CSRF-Token': editor.config.drupalMedia_previewCsrfToken
},
success: function success(previewHtml, textStatus, jqXhr) {
_this3.element.setHtml(previewHtml);
_this3.setData('label', jqXhr.getResponseHeader('Drupal-Media-Label'));
Expand Down
30 changes: 30 additions & 0 deletions modules/media/src/Controller/MediaFilterController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
use Drupal\Core\Entity\ContentEntityStorageInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\filter\FilterFormatInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
Expand Down Expand Up @@ -93,6 +95,8 @@ public static function create(ContainerInterface $container) {
* @see \Drupal\editor\EditorController::getUntransformedText
*/
public function preview(Request $request, FilterFormatInterface $filter_format) {
self::checkCsrf($request, \Drupal::currentUser());

$text = $request->query->get('text');
$uuid = $request->query->get('uuid');
if ($text == '' || $uuid == '') {
Expand Down Expand Up @@ -140,4 +144,30 @@ public static function formatUsesMediaEmbedFilter(FilterFormatInterface $filter_
->addCacheableDependency($filter_format);
}

/**
* Throws an AccessDeniedHttpException if the request fails CSRF validation.
*
* This is used instead of \Drupal\Core\Access\CsrfAccessCheck, in order to
* allow access for anonymous users.
*
* @todo Refactor this to an access checker.
*/
private static function checkCsrf(Request $request, AccountInterface $account) {
$header = 'X-Drupal-MediaPreview-CSRF-Token';

if (!$request->headers->has($header)) {
throw new AccessDeniedHttpException();
}
if ($account->isAnonymous()) {
// For anonymous users, just the presence of the custom header is
// sufficient protection.
return;
}
// For authenticated users, validate the token value.
$token = $request->headers->get($header);
if (!\Drupal::csrfToken()->validate($token, $header)) {
throw new AccessDeniedHttpException();
}
}

}
4 changes: 3 additions & 1 deletion modules/media/src/Plugin/CKEditorPlugin/DrupalMedia.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ public function getFile() {
* {@inheritdoc}
*/
public function getConfig(Editor $editor) {
return [];
return [
'drupalMedia_previewCsrfToken' => \Drupal::csrfToken()->get('X-Drupal-MediaPreview-CSRF-Token'),
];
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace Drupal\Tests\media\FunctionalJavascript;

use Drupal\Component\Utility\Html;
use Drupal\Core\Url;
use Drupal\editor\Entity\Editor;
use Drupal\field\Entity\FieldConfig;
use Drupal\file\Entity\File;
Expand Down Expand Up @@ -1027,14 +1026,13 @@ public function linkabilityProvider() {
* @dataProvider previewAccessProvider
*/
public function testEmbedPreviewAccess($media_embed_enabled, $can_use_format) {
$format = FilterFormat::create([
'format' => $this->randomMachineName(),
'name' => $this->randomString(),
'filters' => [
'filter_align' => ['status' => TRUE],
'filter_caption' => ['status' => TRUE],
'media_embed' => ['status' => $media_embed_enabled],
],
// Reconfigure the host entity's text format to suit our needs.
/** @var \Drupal\filter\FilterFormatInterface $format */
$format = FilterFormat::load($this->host->body->format);
$format->set('filters', [
'filter_align' => ['status' => TRUE],
'filter_caption' => ['status' => TRUE],
'media_embed' => ['status' => $media_embed_enabled],
]);
$format->save();

Expand All @@ -1045,24 +1043,23 @@ public function testEmbedPreviewAccess($media_embed_enabled, $can_use_format) {
$permissions[] = $format->getPermissionName();
}
$this->drupalLogin($this->drupalCreateUser($permissions));

$text = '<drupal-media data-caption="baz" data-entity-type="media" data-entity-uuid="' . $this->media->uuid() . '"></drupal-media>';
$route_parameters = ['filter_format' => $format->id()];
$options = [
'query' => [
'text' => $text,
'uuid' => $this->media->uuid(),
],
];
$this->drupalGet(Url::fromRoute('media.filter.preview', $route_parameters, $options));
$this->drupalGet($this->host->toUrl('edit-form'));

$assert_session = $this->assertSession();
if ($media_embed_enabled && $can_use_format) {
$assert_session->elementExists('css', 'img');
$assert_session->responseContains('baz');
if ($can_use_format) {
$this->waitForEditor();
$this->assignNameToCkeditorIframe();
$this->getSession()->switchToIFrame('ckeditor');
if ($media_embed_enabled) {
$this->assertNotEmpty($assert_session->waitForElementVisible('css', 'article.media'));
}
else {
$assert_session->assertWaitOnAjaxRequest();
$assert_session->elementNotExists('css', 'article.media');
}
}
else {
$assert_session->responseContains('You are not authorized to access this page.');
$assert_session->pageTextContains('This field has been disabled because you do not have sufficient permissions to edit it.');
}
}

Expand Down

0 comments on commit 6b60b88

Please sign in to comment.