diff --git a/core/modules/filter/config/schema/filter.schema.yml b/core/modules/filter/config/schema/filter.schema.yml index b45a475595..a47cc5a689 100644 --- a/core/modules/filter/config/schema/filter.schema.yml +++ b/core/modules/filter/config/schema/filter.schema.yml @@ -60,6 +60,16 @@ filter_settings.filter_html: type: boolean label: 'HTML nofollow' +filter_settings.filter_html_image_secure: + type: filter + label: 'Restrict images to this site' + mapping: + domains: + type: sequence + label: 'Accepted domains' + sequence: + - type: string + label: 'Domain name' filter_settings.filter_url: type: filter diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module index e1d3657574..4e21273592 100644 --- a/core/modules/filter/filter.module +++ b/core/modules/filter/filter.module @@ -770,7 +770,7 @@ function _filter_html_escape($text) { /** * Process callback for local image filter. */ -function _filter_html_image_secure_process($text) { +function _filter_html_image_secure_process($text, array $domains) { // Find the path (e.g. '/') to Drupal root. $base_path = base_path(); $base_path_length = mb_strlen($base_path); @@ -783,8 +783,20 @@ function _filter_html_image_secure_process($text) { foreach ($images as $image) { $src = $image->getAttribute('src'); // Transform absolute image URLs to relative image URLs: prevent problems on - // multisite set-ups and prevent mixed content errors. - $image->setAttribute('src', file_url_transform_relative($src)); + // multisite set-ups and prevent mixed content errors. Use the configured + // list of allowed domains, if set. + if (!empty($domains)) { + $url = parse_url($src); + // If the URL has a host, check if it is in the list of allowed domains. + if (isset($url['host']) && isset($url['path']) && in_array($url['host'], $domains, TRUE)) { + // Only images in the filesystem will pass verification, do not bother + // with query. + $image->setAttribute('src', $url['path']); + } + } + else { + $image->setAttribute('src', file_url_transform_relative($src)); + } // Verify that $src starts with $base_path. // This also ensures that external images cannot be referenced. diff --git a/core/modules/filter/src/Plugin/Filter/FilterHtmlImageSecure.php b/core/modules/filter/src/Plugin/Filter/FilterHtmlImageSecure.php index 8b574d749c..960f68ce49 100644 --- a/core/modules/filter/src/Plugin/Filter/FilterHtmlImageSecure.php +++ b/core/modules/filter/src/Plugin/Filter/FilterHtmlImageSecure.php @@ -13,6 +13,10 @@ * title = @Translation("Restrict images to this site"), * description = @Translation("Disallows usage of <img> tag sources that are not hosted on this site by replacing them with a placeholder image."), * type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE, + * settings = { + * domains = { + * } + * }, * weight = 9 * ) */ @@ -22,7 +26,7 @@ class FilterHtmlImageSecure extends FilterBase { * {@inheritdoc} */ public function process($text, $langcode) { - return new FilterProcessResult(_filter_html_image_secure_process($text)); + return new FilterProcessResult(_filter_html_image_secure_process($text, $this->settings['domains'])); } /**