diff --git a/includes/common.inc b/includes/common.inc
index ceac115..0d26a0b 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -1610,6 +1610,7 @@ function _filter_xss_attributes($attr) {
           $thisval = filter_xss_bad_protocol($match[1]);
 
           if (!$skip) {
+            _filter_xss_ie_fix_attr_value($thisval);
             $attrarr[] = "$attrname=\"$thisval\"";
           }
           $working = 1;
@@ -1622,6 +1623,7 @@ function _filter_xss_attributes($attr) {
           $thisval = filter_xss_bad_protocol($match[1]);
 
           if (!$skip) {
+            _filter_xss_ie_fix_attr_value($thisval);
             $attrarr[] = "$attrname='$thisval'";
           }
           $working = 1; $mode = 0;
@@ -1633,6 +1635,7 @@ function _filter_xss_attributes($attr) {
           $thisval = filter_xss_bad_protocol($match[1]);
 
           if (!$skip) {
+            _filter_xss_ie_fix_attr_value($thisval);
             $attrarr[] = "$attrname=\"$thisval\"";
           }
           $working = 1; $mode = 0;
@@ -1666,6 +1669,22 @@ function _filter_xss_attributes($attr) {
 }
 
 /**
+ * Fix for IE < 9 broken handling of ` character.
+ *
+ * @param $string
+ *   Attribute value to be modified by reference.
+ */
+function _filter_xss_ie_fix_attr_value(&$string) {
+  if (strpos($string, '`') !== FALSE) {
+    // IE < 9 quoting would already be triggered by the presence of any "' <>
+    if (!preg_match('/["\' <>]/', $string)) {
+      // Trailing space triggers IE < 9 to correctly quote the value.
+      $string .= ' ';
+    }
+  }
+}
+
+/**
  * Processes an HTML attribute value and strips dangerous protocols from URLs.
  *
  * @param $string
@@ -2419,7 +2438,7 @@ function drupal_http_header_attributes(array $attributes = array()) {
 function drupal_attributes(array $attributes = array()) {
   foreach ($attributes as $attribute => &$data) {
     $data = implode(' ', (array) $data);
-    $data = $attribute . '="' . check_plain($data) . '"';
+    $data = $attribute . '="' . _filter_xss_ie_fix_attr_value(check_plain($data)) . '"';
   }
   return $attributes ? ' ' . implode(' ', $attributes) : '';
 }
diff --git a/modules/filter/filter.test b/modules/filter/filter.test
index ddea6af..0f42636 100644
--- a/modules/filter/filter.test
+++ b/modules/filter/filter.test
@@ -1128,6 +1128,11 @@ class FilterUnitTestCase extends DrupalUnitTestCase {
 
     $f = filter_xss("Who&amp;amp;#039; Online");
     $this->assertNormalized($f, "who&amp;#039; online", 'HTML filter -- double encoded html entity number');
+
+    // Check a space is appended to the attribute whenever the attribute value
+    // contains the accent character. @see _filter_xss_ie_fix_attr_value()
+    $text = filter_xss('<input value="``onmouseover=alert(1)">', array('input'));
+    $this->assertEqual($text, '<input value="``onmouseover=alert(1) ">');
   }
 
   /**
diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test
index bf85576..c836104 100644
--- a/modules/simpletest/tests/common.test
+++ b/modules/simpletest/tests/common.test
@@ -2772,6 +2772,7 @@ class DrupalAttributesUnitTest extends DrupalUnitTestCase {
     // Verify empty attribute values are rendered.
     $this->assertIdentical(drupal_attributes(array('alt' => '')), ' alt=""', 'Empty attribute value #1.');
     $this->assertIdentical(drupal_attributes(array('alt' => NULL)), ' alt=""', 'Empty attribute value #2.');
+    $this->assertIdentical(drupal_attributes(array('alt' => '``onmouseover=alert(1)')), ' alt="``onmouseover=alert(1) "');
 
     // Verify multiple attributes are rendered.
     $attributes = array(
