In August 2014 I found a severe cross-site scripting security vulnerability in the latest version (1.13.0) of the ‘jQuery Validation Plugin‘ during a security penetration test for a customer. This jQuery plugin which adds easy form validation functionality to a web site, is written by a core developer of the highly popular jQuery JavaScript framework.

As of speaking this vulnerability still exists and hasn’t been patched. It seems that on first sight 6.000+ web sites are vulnerable. jQuery hasn’t responded to my report of this vulnerability. That’s why I chose for full public disclosure, so other jQuery users can inform themselves about the safety of this validation plugin.

Timeline

August 20, 2014

I reported this vulnerability to the developer of this plugin via his personal e-mail address. Did not get a response from him.

September 8, 2014

Sent him a reminder. Still got no response.

November 7, 2014

As a last resort I disclosed this vulnerability to the generic jQuery functional e-mail account ([email protected]).

November 13, 2014

Notified the generic jQuery e-mail account and the plugin developer about my intention to publicly release this vulnerability in the upcoming days. Again I didn’t get any response on this e-mail.

November 14, 2014

Just checked and the vulnerability is still not fixed in their latest version (1.13.1).

November 18, 2014

Full public disclosure on this web log.

Searching in their bug tracker

I was curious if this cross-site scripting vulnerability was added to their bug tracker after my disclosure. Couldn’t find it. Then I searched further if this plugin had other security vulnerabilities in the past. Someone posted on their bug tracker:



Apparently I’m not the only one who didn’t get any feedback from this developer.

After 7 months (!) the developer responded to this bug report and closes it a few days later:



I was shocked. This vulnerability is known since June 2011. That’s already 3.5 years. The developer thinks it’s “not a big deal”.

When I perform a security assessment as part of a quality assurance process, most of the time this kind of vulnerability poses a high security risk to a company. Such security finding is blocking a new software release from going to production from a security policy point of view. So, that’s certainly a big deal.

Searching Google to find vulnerable web sites

When writing this article, I wanted to know how wide spread this vulnerability was. So I quickly crafted a few Google Dorks to find vulnerable web sites.

By looking into the vulnerable source code of the jQuery Validation Plugin, I found a text string that would indicate candidate sites that might be vulnerable. Google returned 12.100 search results when searching for this string:

Google returned 257 entries when searching for the default location of the vulnerable file:

It’s frightening to know that it’s only a tip of the iceberg of what Google can find. There will be a lot more vulnerable web sites than the 12.100 + 257 web sites that I quickly found via a simple search query.

12.000+ pages seem to be vulnerable

When browsing through a few search results, I quickly found multiple vulnerable web sites. First impression is that more than 12.000 pages are vulnerable to cross-site scripting. That translates to about 6.000 web sites. That’s serious!

Open Source Vulnerability Database: vulnerability #99044

Saw something interesting when browsing the search results of the second Google Dork above. Someone else also found this vulnerability and disclosed it on October 26, 2013 on the Open Source Vulnerability Database (OSVDB) web site:



Clearly I’m not the first security researcher that found this problem, and certainly not the only one who worries about it.

Sadly, the plugin developer seems to be careless about security and leaves his software and users vulnerable. Even after multiple security researchers expressed their concerns to him.

Technical vulnerability details: full disclosure

The vulnerability exists in a CAPTCHA demonstration script.

Location

On line 69 in /demo/captcha/index.php the PHP variable $_SERVER[‘PHP_SELF’] is printed without any user input sanitation:

[..] <a href=”<?php echo $_SERVER[‘PHP_SELF’]; ?>” id=”refreshimg” title=”Click to refresh image”> [..]

Exploit

This make JavaScript injection possible by requesting the following URL:

http://www.example.com/demo/captcha/index.php/”><script>alert(1)</script><br%20alt=”

Evidence

The following HTML will be printed by the web server:

[..] <a href=”/demo/captcha/index.php/”><script>alert(1)</script><br alt=”” id=”refreshimg” title=”Click to refresh image”> [..]

The injected JavaScript code ‘<script>alert(1)</script>’ will be rendered by a web browser:

Impact

With this severe vulnerability session hijacking is possible in most cases via a reflected cross-site scripting attack, which can result in identity theft (if session cookies aren’t protected via HttpOnly).

Solution

When installing or maintaining the jQuery Validation Plugin, remove the ‘/demo/’ folder entirely. Most of the time you don’t need this demonstration script anyway.

When you’ve copied and implemented this demonstration script, then use PHP’s function htmlEntities() to secure it:

[..] <a href=”<?php echo htmlEntities($_SERVER[‘PHP_SELF’], ENT_QUOTES); ?>” id=”refreshimg” title=”Click to refresh image”> [..]

The htmlEntities() function will neutralize injected JavaScript code and thus eliminates the cross-site scripting vulnerability.

Perform forensic analysis

When you’ve found out that your web site was vulnerable to this attack, then you should perform a forensic analysis to see if someone attacked your web site in the past. You can know this by searching for extraordinary requests that are made to the vulnerable file URL(s).

Vulnerability root cause analysis

On line 66 in file /demo/captcha/index.php, the following credits are given by the author of the jQuery Validation Plugin:

[..] CAPTCHA [..], based on [..] http://psyrens.com/captcha/[..]

Perhaps he didn’t introduced the vulnerability himself, but copied it from the original author of the CAPTCHA script. Too bad that the mentioned web site in the CAPTCHA script is offline. But luckily Google doesn’t seem to forget anything:

One of the search results pointed to a forum post from April 5, 2009, which quotes part of the original CAPTCHA code:

As it seems, the cross-site scripting vulnerability was introduced by the developer of the CAPTCHA script and not by author of the jQuery Validation Plugin.

When browsing further through the search results, I’ve seen instances of this CAPTCHA script that date from 2007. This is confirmed by looking at the Wayback Machine from the Internet Archive for http://psyrens.com/captcha/:

I’ve managed to obtain a copy of the code of the original CAPTCHA script via the Wayback Machine dated from March 24, 2007.

This vulnerability was introduced probably around eight years ago and copied to all kinds of web sites and software products.

When browsing through the archived web site where this CAPTCHA script originated from, I discovered that the author of this script was probably 17 years old when he created it:

(A funny detail is that the site stated that it had been hacked recently. I’ve put a screenshot of the accompanying news article below)

Looking for vulnerable web sites that implemented this CAPTCHA script

The author of the jQuery Validation Plugin used a different text string in his script than the author of the CAPTCHA script. When I searched Google for the text string that’s inside the original CAPTCHA script, Google returned 8.100 search results:

This security bug seems to have spread to tens of thousands of web sites since its creation. It’s a wild guess, but I would not be surprised if there are around 20.000 web sites affected by this security bug.

The bigger picture

The jQuery and CAPTCHA authors are certainly not the only one struggling with this specific cross-site scripting vulnerability as Google again shows us:

Combined the above search queries returned 322.300 results. An astonishing amount.

Note that server side running PHP source code is never published on a web site, so all those Google search results display web developers that are talking about their code and showing their code to others. That means that the PHP code that Google found is running on millions of websites. And thus a large amount of those web sites have cross-site scripting vulnerabilities (!). That’s a big problem.

Final words

What started as a vulnerability that seemed to be only active in one product where I performed a security test on, soon became larger (jQuery Validation Plugin) and larger (a CATPCHA implementation) and uncovered quite a story behind it. This story is about taking responsibility for any code that ships with your software and taking security serious. This story is also about knowing where your code came from, who wrote it and the habit of blindly copying code with all kind of security implications.

This story also shines its light on how easy it is to find vulnerable web sites. There are lots of tools like Google available where a simple search query will list lots of hackable web sites. There are also a lot more vulnerabilities to search for; cross-site scripting is certainly not the only thread to watch out for.

At this moment, there are millions of web sites vulnerable to cross-site scripting attacks. The most shocking part is that all those web site owners don’t even know about it and think their web site is safe. We still have a lot to accomplish to get towards a web that is safe.

Update November 19, 2014 19:00

Within 17 hours that I went full public disclosure of the vulnerability in the jQuery Validation Plugin, the developer patched it:

Full disclosure works! :-)

News sites linking to this story