prettyPhoto DOM based XSS on Saotn.org… This evening, after tweeting about preventing cross site scripting vulnerabilities, I received a reply from Olivier Beg. His reply to my tweet contained an image, as you can see above. He alerted me that Saotn.org was vulnerable to a DOM based XSS vulnerability, hidden in prettyPhoto used by my WordPress theme. Whoops! So, I had work to do! But, what is prettyPhoto and what exactly is a DOM based XSS?
Table of Contents
About PrettyPhoto DOM XSS
PrettyPhoto is widely used in various WordPress themes and plugins. Olivier was very helpful in identifying the Cross Site Scripting (XSS) source, which gave me a nice starting point to search for a solution.
It turns out, this DOM based XSS exists in prettyPhoto for quite some time. I easily found a reference on Packetstorm and several other blog posts (DOM XSS in w3af.org: Fixed!, Kali Linux DOM Based XSS Writeup) describing this vulnerability, possibly in other versions of prettyPhoto.
The following URL discusses a fix I decided to implement: https://github.com/Duncaen/prettyphoto/commit/3ef0ddfefebbcc6bbe9245f9cea87e26838e9bbc.
Why this prettyPhoto XSS is (can be) dangerous
This XSS is dangerous because an admin user can be tricked into clicking a specially crafted link, hosting a script to steal the
document.cookie. Imagine the following URL, which triggers the DOM XSS:
document.cookie information is sent to www.evil-attacker.org/sendcookie.php when an admin user clicks such a link. Mark it up with some pretty HTML, to form something interesting and you’d be surprised…
prettyPhoto XSS impact on WordPress
The impact of this DOM XSS on WordPress is pretty much non existent. WordPress fortunately uses HttpOnly cookies. HttpOnly is an additional flag included in a Set-Cookie HTTP response header. Using the HttpOnly flag when generating a cookie helps mitigate the risk of client side script accessing the protected cookie (Source: OWASP).
prettyPhoto is a jQuery lightbox clone. Not only does it support images, it also support for videos, flash, YouTube, iframes and ajax. It’s a full blown media lightbox.
It is very easy to setup, yet very flexible if you want to customize it a bit. Plus the script is compatible in every major browser, even IE6. It also comes with useful APIs so prettyPhoto can be launched from nearly anywhere (yes, that includes Flash)!
What is a DOM based XSS
DOM Based XSS (or as it is called in some texts, “type-0 XSS”) is an XSS attack wherein the attack payload is executed as a result of modifying the DOM “environment” in the victim’s browser used by the original client side script, so that the client side code runs in an “unexpected” manner. That is, the page itself (the HTTP response that is) does not change, but the client side code contained in the page executes differently due to the malicious modifications that have occurred in the DOM environment.
This is in contrast to other XSS attacks (stored or reflected), wherein the attack payload is placed in the response page (due to a server side flaw).
Yan Zhu, a staff technologist at the Electronic Frontier Foundation, found that an attacker could hijack a WordPress users cookie, when the user is connected through an unsecure, public Wi-Fi network. For the wordpress_logged_in_ cookie, the parameter Secure isn’t set which causes the cookie being transmitted in plain text (not encrypted).
prettyPhoto DOM XSS impact on other sites
As stated above, WordPress is pretty secured against this particular Cross Site Scripting vulnerability. However, since prettyPhoto is easy to integrate in websites, all websites not having HttpOnly cookies might be vulnerable!
How to fix prettyPhoto DOM based XSS
You can fix the DOM based XSS in prettyPhoto by opening up
jquery.prettyPhoto.js in your favorite editor. Scroll to line 876 and add the lines:
// xss prevention hashIndex = parseInt(hashIndex); hashRel = hashRel.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/])/g,'\\$1');
At least versions 3.1.4 and 3.1.5 of prettyPhoto, depending on your download source, are vulnerable to this DOM based XSS. As always, test such code fixes first before putting it in production!
Be careful: The version you can download from the Github fork is secured with this fix, but might contain a typo. The latest version from no-margin-for-errors.com is not secured!