diff --git a/core/includes/common.inc b/core/includes/common.inc index f656206..5225b8a 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -2929,8 +2929,8 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) { // with how render cached output gets stored. This ensures that // #post_render_cache callbacks get the same data to work with, no matter if // #cache is disabled, #cache is enabled, there is a cache hit or miss. - $prefix = isset($elements['#prefix']) ? $elements['#prefix'] : ''; - $suffix = isset($elements['#suffix']) ? $elements['#suffix'] : ''; + $prefix = isset($elements['#prefix']) ? SafeMarkup::checkAdminXss($elements['#prefix']) : ''; + $suffix = isset($elements['#suffix']) ? SafeMarkup::checkAdminXss($elements['#suffix']) : ''; $elements['#markup'] = $prefix . $elements['#children'] . $suffix; // We've rendered this element (and its subtree!), now update the stack. diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 723ae63..c3cbcec 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -382,7 +382,19 @@ function _theme($hook, $variables = array()) { drupal_render($preprocess_attached, TRUE); } } - + // Check the elements for insecure HTML and pass through sanitization. + if (isset($variables['element'])) { + $markup_keys = array( + '#description', + '#field_prefix', + '#field_suffix', + ); + foreach ($markup_keys as $key) { + if (!empty($variables['element'][$key]) && is_scalar($variables['element'][$key])) { + $variables['element'][$key] = SafeMarkup::checkAdminXss($variables['element'][$key]); + } + } + } // Generate the output using either a function or a template. $output = ''; if (isset($info['function'])) { diff --git a/core/lib/Drupal/Component/Utility/SafeMarkup.php b/core/lib/Drupal/Component/Utility/SafeMarkup.php index dc0a6a1..cf53650 100644 --- a/core/lib/Drupal/Component/Utility/SafeMarkup.php +++ b/core/lib/Drupal/Component/Utility/SafeMarkup.php @@ -6,7 +6,7 @@ */ namespace Drupal\Component\Utility; - +use Drupal\Component\Utility\Xss; /** * Manages known safe strings for rendering at the theme layer. * @@ -137,6 +137,22 @@ public static function escape($string) { } /** + * Applies a very permissive XSS/HTML filter for admin-only use. + * + * @param string $string + * A string containing the HTML that needs to be verified. + * + * @return string + * The escaped string. If $string was already set as safe with + * SafeString::set, it won't be escaped again. + * + * @see \Drupal\Component\Utility\Xss\filterAdmin + */ + public static function checkAdminXss($string) { + return static::isSafe($string) ? $string : Xss::filterAdmin($string); + } + + /** * Retrieves all strings currently marked as safe. * * This is useful for the batch and form APIs, where it is important to diff --git a/core/lib/Drupal/Core/Render/Element/HtmlTag.php b/core/lib/Drupal/Core/Render/Element/HtmlTag.php index 851bbf9..5f81e93 100644 --- a/core/lib/Drupal/Core/Render/Element/HtmlTag.php +++ b/core/lib/Drupal/Core/Render/Element/HtmlTag.php @@ -139,7 +139,8 @@ public static function preRenderConditionalComments($element) { $expression = '!IE'; } else { - $expression = $browsers['IE']; + // Need to filter at least for admin usage. + $expression = SafeMarkup::checkAdminXss($browsers['IE']); } // Wrap the element's potentially existing #prefix and #suffix properties with @@ -151,15 +152,23 @@ public static function preRenderConditionalComments($element) { '#prefix' => '', '#suffix' => '', ); + + // Ensure what we are dealing with is safe. + // This would be done later anyway in drupal_render(). + $prefix = SafeMarkup::checkAdminXss($element['#prefix']); + $suffix = SafeMarkup::checkAdminXss($element['#suffix']); + + // Now calling SafeMarkup::set is safe, because we ensured the + // data coming in was at least admin escaped. if (!$browsers['!IE']) { // "downlevel-hidden". - $element['#prefix'] = "\n\n"; + $element['#prefix'] = SafeMarkup::set("\n\n"); } else { // "downlevel-revealed". - $element['#prefix'] = "\n\n" . $element['#prefix']; - $element['#suffix'] .= "\n"; + $element['#prefix'] = SafeMarkup::set("\n\n" . $prefix); + $element['#suffix'] = SafeMarkup::set($suffix . "\n"); } return $element;