To cover and fix this security vulnerability https://www.drupal.org/sa-contrib-2022-042 now the EmbedController in its public function preview(Request $request, FilterFormatInterface $filter_format) { is checking for a Header with a CSRF Token. If the header is not set, it will throw an AccessDenied exception so the response will error with a 403 Forbidden status.
public function preview(Request $request, FilterFormatInterface $filter_format) {
+ self::checkCsrf($request, \Drupal::currentUser());
Changes:
- New required Header:
X-Drupal-EmbedPreview-CSRF-Tokenshould be set with a CSRF Token in the request
Each CKEditor Plugin using the EmbedController (ie: using path /embed/preview/{filter_format} ) should take care of implementing the new Header in the request.
Before
N/A
After
In the CKEditor plugin definition, you add the token for the header:
namespace Drupal\my_module\Plugin\CKEditorPlugin;
use Drupal\editor\Entity\Editor;
use Drupal\embed\EmbedCKEditorPluginBase;
/**
* Defines the "mylovelyplugin" plugin.
*
* @CKEditorPlugin(
* id = "mylovelyplugin",
* label = @Translation("My Lovely Plugin"),
* embed_type_id = "url"
* )
*/
class MyLovelyPlugin extends EmbedCKEditorPluginBase {
public function getConfig(Editor $editor) {
return [
+ 'MyLovelyPlugin_previewCsrfToken' => \Drupal::csrfToken()->get('X-Drupal-EmbedPreview-CSRF-Token'),
];
}
An then, in the JavaScript creating the request to the preview path, you set the new Header added in the plugin:
MyLovelyPluginPreview.options.headers = {
'X-Drupal-EmbedPreview-CSRF-Token': editor.config.MyLovelyPlugin_previewCsrfToken
};
MyLovelyPluginPreview.execute();
You can see as example the drupalentity plugin in Contrib entity_embed which is implementing the same header for the EmbedController.
Plugin: https://git.drupalcode.org/project/entity_embed/-/blob/8.x-1.x/src/Plugi...
Javascript: https://git.drupalcode.org/project/entity_embed/-/blob/8.x-1.x/js/plugin...