diff --git a/core/includes/common.inc b/core/includes/common.inc
index b88a63c..5d76109 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -1121,6 +1121,8 @@ function _filter_xss_split($m, $store = FALSE) {
  *   Cleaned up version of the HTML attributes.
  */
 function _filter_xss_attributes($attr) {
+  static $allowed_attributes;
+
   $attrarr = array();
   $mode = 0;
   $attrname = '';
@@ -1136,7 +1138,14 @@ function _filter_xss_attributes($attr) {
         if (preg_match('/^([-a-zA-Z]+)/', $attr, $match)) {
           $attrname = strtolower($match[1]);
           $skip = ($attrname == 'style' || substr($attrname, 0, 2) == 'on');
+          if (!isset($allowed_attributes)) {
+            // filter_xss_admin() is called by the installer and update.php, in which
+            // case the configuration may not exist (yet). Provide a minimal default set
+            // of allowed protocols for these cases.
+            $allowed_attributes = array_flip(config('system.filter')->get('attributes') ?: array('alt', 'lang', 'title', 'rel', 'value'));
+          }
           $working = $mode = 1;
+            $test = array_flip(config('system.filter')->get('protocols') ?: array('test', 'lang', 'title', 'rel', 'value'));
           $attr = preg_replace('/^[-a-zA-Z]+/', '', $attr);
         }
         break;
@@ -1161,19 +1170,28 @@ function _filter_xss_attributes($attr) {
       case 2:
         // Attribute value, a URL after href= for instance.
         if (preg_match('/^"([^"]*)"(\s+|$)/', $attr, $match)) {
-          $thisval = filter_xss_bad_protocol($match[1]);
+          if (!isset($allowed_attributes[strtolower($attrname)])) {
+            $thisval = filter_xss_bad_protocol($match[1]);
+          }
+          else {
+            $thisval = $match[1];
+          }
 
           if (!$skip) {
             $attrarr[] = "$attrname=\"$thisval\"";
           }
-          $working = 1;
-          $mode = 0;
+          $working = 1; $mode = 0;
           $attr = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr);
           break;
         }
 
         if (preg_match("/^'([^']*)'(\s+|$)/", $attr, $match)) {
-          $thisval = filter_xss_bad_protocol($match[1]);
+          if (!isset($allowed_attributes[strtolower($attrname)])) {
+            $thisval = filter_xss_bad_protocol($match[1]);
+          }
+          else {
+            $thisval = $match[1];
+          }
 
           if (!$skip) {
             $attrarr[] = "$attrname='$thisval'";
@@ -1184,7 +1202,12 @@ function _filter_xss_attributes($attr) {
         }
 
         if (preg_match("%^([^\s\"']+)(\s+|$)%", $attr, $match)) {
-          $thisval = filter_xss_bad_protocol($match[1]);
+          if (!isset($allowed_attributes[strtolower($attrname)])) {
+            $thisval = filter_xss_bad_protocol($match[1]);
+          }
+          else {
+            $thisval = $match[1];
+          }
 
           if (!$skip) {
             $attrarr[] = "$attrname=\"$thisval\"";
diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml
index d41d414..c6822b8 100644
--- a/core/modules/system/config/schema/system.schema.yml
+++ b/core/modules/system/config/schema/system.schema.yml
@@ -127,6 +127,12 @@ system.filter:
       sequence:
         - type: string
           label: 'Protocol'
+    attributes:
+      type: sequence
+      label: 'Allowed attributes'
+      sequence:
+        - type: string
+          label: 'Attribute'
 
 system.logging:
   type: mapping
diff --git a/core/modules/system/config/system.filter.yml b/core/modules/system/config/system.filter.yml
index 3bfbd9a..f5d5df3 100644
--- a/core/modules/system/config/system.filter.yml
+++ b/core/modules/system/config/system.filter.yml
@@ -11,3 +11,47 @@ protocols:
   - sftp
   - webcal
   - rtsp
+
+attributes:
+  - alt
+  - lang
+  - title
+  - rel
+  - value
+  - align
+  - alink
+  - bgcolor
+  - border
+  - cellpadding
+  - cellspacing
+  - class
+  - color
+  - cols
+  - colspan
+  - coords
+  - dir
+  - face
+  - height
+  - hspace
+  - ismap
+  - marginheight
+  - marginwidth
+  - multiple
+  - nohref
+  - noresize
+  - noshade
+  - nowrap
+  - ref
+  - rev
+  - rows
+  - rowspan
+  - scrolling
+  - shape
+  - span
+  - summary
+  - tabindex
+  - usemap
+  - valign
+  - vlink
+  - vspace
+  - width
