1
<?xml version=
"1.0" encoding=
"UTF-8"?>
2 <!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5 xmlns=
"http://www.w3.org/1999/xhtml"
6 xmlns:
xi=
"http://www.w3.org/2001/XInclude"
9 <title>CSS Quoting Full Disclosure - Security - HTML Purifier
</title>
10 <xi:include href=
"common-meta.xml" xpointer=
"xpointer(/*/node())" />
11 <meta name=
"description" content=
"Full disclosure security page detailing the CSS quoting attack." />
12 <meta name=
"keywords" content=
"HTMLPurifier, HTML Purifier, HTML, filter, filtering, standards, compliant, 4.1.1, attack, full disclosure, xss, security, quoting, css, internet explorer" />
16 <xi:include href=
"common-header.xml" xpointer=
"xpointer(/*/node())" />
19 <h1 id=
"title">CSS Quoting Full Disclosure
</h1>
24 Non-standard parsing behavior of strings in CSS expressions in
25 Internet Explorer could allow a clever attacker to escape the string
26 and execute arbitrary JavaScript via CSS. The two CSS properties that
27 HTML Purifier enabled that take strings as inputs are
28 <code>background-image
</code>,
<code>background
</code> and
29 <code>font-family
</code>; instances of HTML Purifier that did not
30 enable these properties were not vulnerable.
34 This vulnerability was reported privately to the vendor by
35 <a href=
"http://mario.heideri.ch/">Mario Heiderich
</a>.
36 <a href=
"http://d.hatena.ne.jp/teracc/">Takeshi Terada
</a>
37 was consulted during the construction of the fix. David Ross of
38 the Internet Explorer team was separately informed of this class of
39 exploits. Shortly prior to the release of
4.1.1, a post
41 href=
"http://sla.ckers.org/forum/read.php?2,34579">sla.ckers.org
</a>
42 was made to sanity check the new proposed fix. No active exploits are
49 There are several quirks in Internet Explorer's parsing of string-like
50 expressions in CSS that caused this security vulnerability. They are as
55 <li>Internet Explorer treats the second instance of an unprotected
56 exclamation mark as a valid ending delimiter for its CSS parser (no
57 semicolon is necessary in this case), and
</li>
58 <li>Internet Explorer does not recognize CSS escape characters
59 <code>\
"</code> and <code>\'</code> in strings.</li>
63 Thus, the original implementation of <code>url()</code> in
64 <code>background-image</code> and friends was vulnerable
65 because it did not use quoting and relied on character escaping, and
66 the original implementation of <code>font-family</code> was vulnerable
67 because it expected to be able to escape internal apostrophes in its
68 string. The initial fix merely added quoting to <code>url()</code>
69 but failed to address Internet Explorer's broken character escaping.
73 At this point, there appeared to be a problem: it seemed impossible to
74 express the full range of permitted URLs and font names: the
75 characters that Internet Explorer did not seem to be able to escape
76 were also valid characters in URLs and font names.
80 URLs were resolved in the following manner: while a single quote was a
81 valid character for a URL, a double quote was not. A backslash was
82 never a valid character. Thus, if the <code>url("...
")</code> form
83 was used, no escaping would be necessary.
87 Font names were resolved in a similar fashion (apostrophes are far
88 more common in font names than double quotes), but with an extra
89 observation made by Takeshi Terada: while Internet Explorer did not
90 support <code>\"</code> style character escapes, it did support
91 hexadecimal character escapes. Thus, quotes and backslashes could be
92 portably preserved in font names.
95 <h2 id=
"History">History
</h2>
98 The vulnerability was reported on April
25,
2010 via email. The first
99 incorrect patch was committed to the public repository on
<a
100 href=
"http://repo.or.cz/w/htmlpurifier.git/commit/da94d3d6acdf417ac890426eb1fd239ba62b042d">April
26,
2010</a>
101 with the summary:
<q>Always quote the contents of url() in CSS.
</q>
102 HTML Purifier
4.1.0 was released on April
26,
2010.
106 On April
27,
2010, Mario Heiderich realized that the fix was
107 insufficient. A long private discussion ensued on possible fixes, but
108 we were unable to determine a solution that would not invalidate
109 previously valid CSS expressions.
113 On May
20,
2010, I contacted Takeshi Terada and we came up with a
114 feasible solution. A patch was committed on
<a
115 href=
"http://repo.or.cz/w/htmlpurifier.git/commit/d3abcb90e30592c619047d878cf9c72b7c5836a3">June
1,
2010</a>
116 with the summary
<q>Rewrite CSS url() and font-family output
117 logic.
</q> HTML Purifier
4.1.1 was released on June
1,
2010.
121 The HTML Purifier team realizes that the month long interval between
122 the discovery of the second security vulnerability and the fix was not
123 ideal, and hopes to maintain a fast turnaround for security
124 vulnerabilities in the future.