Discovering a stored XSS that affects over 900k websites (CVE-2016-9751)

In my free time when I’m not hunting for bugs in paid programs, I like to contribute a bit to the open-source community and check for vulnerabilities that might arise. In doing so, I found a stored cross-site scripting vulnerability that affected over 900,000 websites… yikes.

The vulnerable application is called Piwigo  – an open source image showcase/album that, according to Google, is active on over 900,000 webpages. The true number is probably higher than that, but that’s just what the original search brings up. It’s commonly a one-click install on many web host platform for image showcases. Anyhow – on to the bug:

Piwigo has an option that allows for a “quick search” of the photo gallery. (Important to note: There are different “themes” that a visitor can choose that changes the way the pictures are displayed and the way the page looks, this will be important to remember later.)

When you enter a payload, the page displays the payload (sanitized properly) – and then saves the search as a number inside the URL. For example, my search URL is:

That number at the end can be changed, so you can see what other keywords people have searched on the site. I’m not sure if this is a good or a bad idea, but that’s not the bug.

The bug is that when you enter a payload in this quick search area and have also selected the elegant theme there is the option to open a “search criteria” page.

It just so happens that on this search rules page… the keywords (or payload) you entered earlier are not sanitized. You end up getting this beautiful pop-up that all of us bug-hunters love to see:

Sidenote: If you’re a bug bounty hunter, it’s always best to use alert(document.domain) instead of alert(1) – it tells you if the payload is actually firing on a domain that is in scope for the program.

Now here is where it gets bad… that URL above is permanently stored on your website – and I think the only way to remove it is if you manually purge the search history from the administrator backend. Below is a picture of where you can perform that purge:

Why is this bad? Well, before I reported this bug, I’d be concerned if an attacker kept a variety of payloads that will still execute even after the website has implemented a patch – since the search is stored in the database before the patch went into place, it makes sense that all the attacker needs to do is direct the victim to the old URL – and the website owner can’t do much if they haven’t purged the search history.

Example of what I mean: At the time of this writing, if you visit the above URL in that picture on, the payload will still execute, even though the vulnerability was fixed a long time ago.

I was assigned (my first ever!) CVE-2016-9751 regarding this vulnerability. A fix ( was implemented after reporting. Webmasters and gallery owners should update to Piwigo 2.9 in order to implement the patch.

Payload used:

"x><img src=a onerror=alert(1)>