Cross-site scripting in millions of web sites

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:

1
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:

2 3
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:

6 v2

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

4 v2

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:

5
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:

XSS in jquery-validate library 2

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:

7

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

8

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/:

12

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:

10 v2

(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)

11

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:

9 v2

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:

13

14

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:

Capture

Full disclosure works! 🙂

News sites linking to this story

  1. Golem
  2. Norse
  3. The Register
  4. Security Week
  5. ITmedia
  6. Daily Network Security Podcast Details
  7. Tester’s web log
  8. Hackerkast #10
  9. Secure My Mind
  10. SecurityLab news and vulnerability page
  11. 360 Broadcast Platform Security
  12. Mainstreet

About Sijmen Ruwhof

Independent IT Security Researcher / Ethical Hacker
This entry was posted in cross-site scripting, Google, php, responsible disclosure. Bookmark the permalink.

62 Responses to Cross-site scripting in millions of web sites

  1. “Cross-site scripting in millions of web sites” (by the use of #jQuery Validation Plugin): http://sijmen.ruwhof.net/

  2. Cengiz Han Sahin (via LinkedIn) says:

    Great blog Sijmen! #blindlycopyingcode!

  3. ‏About some people in the industry not taking security seriously. #jQuery #goodblogpost

  4. Brenno de Winter (via Facebook) says:

    Dit is een pijnlijk verhaal van Sijmen. Heb nog geprobeerd reactie te krijgen, maar geen antwoord http://sijmen.ruwhof.net/… #triest

  5. Daan van Rooijen (via Facebook) says:

    Als een ontwikkelaar zo traag en nonchalant met veiligheidsissues omgaat moet je al zijn andere code ook wantrouwen, en mag je je zelfs afvragen of hij de zwakheden niet opzettelijk heeft ingebouwd.

    • Osman Mrzljak says:

      Daan! Opzettelijk ? Nee, Daar is hij te jong voor

    • Terecht punt. De andere code van deze ontwikkelaar zal ook wel met dezelfde aandacht voor beveiliging ontwikkeld zijn. Denk overigens niet dat dit lek opzettelijk is geweest, daar is het veel te evident voor.

  6. Mark Bergman (via Facebook) says:

    Nice Good find! 🙂

    Good to report though that the vuln isn’t in the immense popular jQuery javascript lib but in the validator serversides php demo code (/demo/captcha/index.php) which offcource is high likely to be reused in projects (as your google dorks have shown)

  7. b's weblog says:

    From weblog: Eine XSS in jQuery, ungefixt seit August

    “[..] Ach Du liebes Bisschen! Da sieht man, dass auch bei Freier Software Full Disclosure das einzig Sinnvolle ist. Wobei das freie Projekt dann trotzdem (oder deswegen) reagieren sollte; auch das scheint bei jQuery nicht gegeben. Ãœber eine andere Lücke: [..]”

  8. “Cross-site scripting in millions of web sites” good read http://sijmen.ruwhof.net/

  9. Oh, and jQuery validation is stuffed too: http://sijmen.ruwhof.net/

  10. Karen stubbs says:

    Just to be clear, this is a problem with the included demo code that only a complete idiot would include when adding jquery validate to their own website. This is a non issue.

  11. How bad written demo #JavaScript code belongs to production? #jquery #validation #xss http://sijmen.ruwhof.net/… #security #hahahah

  12. Great new research on a serious XSS flaw in jQuery by Dutch security researcher Sijmen Ruwhof. Good work Sijmen! http://sijmen.ruwhof.net/

  13. Sijmen, good description and research. I would like to mention two things:
    – You wrote “a severe cross-site scripting security vulnerability in the latest version (1.13.0) of the ‘jQuery Validation Plugin‘. But vulnerability is not in plugin it self but in its Demo code. Everybody knows that demo parts should be considers as fully working distribution.
    – A fact Google gives you 22 345 hits on some search string is not certainty at all that there are 22 345 sites having “search pattern”. But it gives some direction.

    Still… this is good example , especially in JavaScript world, how much knowledge and attention we spend on security. I am not worried about mistakes developers make (we are also people, non error prone machine), but I am worried about that when you point them to it they just ignore it (or even don’t understand).

    Keep writing on this, and post details. Only transparency will bring us to better web.

    Two examples (in dutch ) : One and Two.

    • Thanks Osman!

      JavaScript developers are often less aware of the dangers of cross-site scripting attacks, as is the case illustrated by the developer of the jQuery Validation Plugin.

  14. If you use the jQuery Validation Plugin you should definitely read this: http://sijmen.ruwhof.net/… #xss #security

  15. 8 year old #xss bug still biting users http://sijmen.ruwhof.net/… #jquery

  16. ‏jQuery Validation Plugin XSS – “Not a big deal” –author http://sijmen.ruwhof.net/

  17. Severe XSS in latest version of ‘jQuery Validation Plugin’ (1.13.0) http://sijmen.ruwhof.net/… < apparently an 0-day, affecting lots of sites

  18. Elger Jonker (via Facebook) says:

    Goed uitgelegd, inzichtelijk en leerzaam. — Zit nu met een soortgelijke situatie: xss op een hele nare plaats. De ontwikkelaar reageert gelukkig wel, maar met “we hebben nog geen meldingen gehad dat sites zijn gehackt, dus maak je geen zorgen.” We zitten op dag 3, dus ik blijf nog even pushen.

  19. Peter Hazenberg (via Facebook) says:

    *zucht* alweer? Oh well… Aan de ene kant, mensen moeten leren dat demo’s en examples er zijn om een bepaalde feature te zien of te leren, niet om integraal te copypasten. Aan de andere kant, demo’s/examples voor veelgebruikte zaken als populaire jQuery plugins mogen wel wat meer secure gemaakt worden.

  20. Une petite XSS dans #jquery. Rien de bien grave, tout le monde maintient cette librairie à jour de toute façon 🙂 http://sijmen.ruwhof.net/

  21. Surprised that a jQuery dev has underestimated XSS for the last 3.5 years! 12,000+ sites vulnerable – http://sijmen.ruwhof.net/

  22. Full disclosure of a jQuery form validation vulnerability. Consider yourself warned. http://sijmen.ruwhof.net/

  23. @securityshell @sruwhof Maybe jquery-validation-1.9.0 1.9.0 isn’t vulnerable? Am I correct? http://sijmen.ruwhof.net/

  24. Apparently @jquery thinks a massive XSS hole in their core Form Validation plugin is “not a big deal”. I kinda beg to differ.

  25. Werk je met jQuery? Dan moet je dit even lezen.
    http://sijmen.ruwhof.net/

  26. Full disclosure of a jQuery + PHP form vulnerability. Patch ’em if you’ve got ’em. http://sijmen.ruwhof.net/

  27. Use the jQuery Validation plugin with caution: http://sijmen.ruwhof.net/… (via @drinks) #jquery #javascript #webdev #websec

  28. Jeroen van der Reijken (via LinkedIn) says:

    Nice one Sijmen 🙂

  29. Ouch! Disclosure of Cross-Site Scripting Vulnerabilities May Impact Millions of Websites http://buff.ly/1xpD3Yk #infosec #security #XSS

  30. A PHP vulnerability isn’t a flaw in a jQuery plugin, it’s a flaw in a demonstration script that users might install along with the plugin. In any case, it’s been patched now.

    • That doesn’t change the fact that a) the dev knew about it for years and didn’t fix it, which leads to b) there are thousands of sites out there that are vulnerable.

      • But he did strike a good chord in how the title might give you the wrong problem. There’s a lot significance in whether it’s a PHP script or a JS script that fails. Server side is the last line, at least for me, when it comes to validating data. Based on the original title I expected the vulnerability to be able to manifest itself even with good server side validation in place, considering the large number mentioned.

  31. Not that it really excuses the non reaction, but this vulnerability appears to be in demo html for the jquery plugin. For this to be in live production code, someone purposefully copied demo code, I call this more of a human error than a code error.

    • This certainly is both a coding and human error.

      You would be amazed how many times I see demonstration or test code ending up in a production environment. It’s a developers job to create secure code, also for demonstration functionality. I’ve seen in my research quite a lot of web sites that purposely copied that code and implemented the CAPTCHA functionality, because I think they thought it was too useful not to use.

      Vulnerable demonstration code has caused a lot of companies and security professionals quite some headache by all the security incidents it generated.

  32. Full disclosure works: http://sijmen.ruwhof.net/… Nice job from @sruwhof

  33. Damn, my mind was violently blown.

  34. Full disclosure works! 🙂
    Also, note how this exploit only works on sites with PHP.
    The lesson here should be: if you d/l a library, just include the used files (*.min.js). Not the demo/etc…

  35. “Cross-site scripting in millions of web sites” http://sijmen.ruwhof.net/… A thrilling read about Ctrl+C Ctrl+V

  36. This is a misleading article in some aspects.

    Yes, there is a XSS vulnerability, but this XSS exist on server side code (the demo PHP page) but jqueryvalidation is a client-side plugin. Although there are DOM Based attacks targeting client-side code this is not one of them.

    The fact that many PHP pages reflect the PHP_SELF variable doesn’t mean they are related to jqueryvalidation plugin in particular. So it is incorrect to point that the vulnerability is related to this jQuery plugin.

    The development team should patch the issue, just for in case some one incorrectly publish the demo part of the plugin on a production site.

    So to people reading this article, 1) Be aware of PHP XSS by using PHP_SELF variable. If you are not doing this and are not publishing the plugin demo pages to the internet, then this specific attack pattern does not apply to you even if you are using the actual plugin.

    • What is exactly misleading?

      The developer of the jQuery Validation Plugin ships a demonstration script with the software package that has a severe vulnerability in it. Even if he didn’t wrote that code himself, he’s still responsible for it.

      As an end user you download the whole package, not only the client-side code.

      Demonstration and test scripts get deployed all the time to production. Senior developers make mistakes and juniors don’t know any better.

  37. Just a friendly dev reminder that it’s usually not a good idea to just dump an entire repository into production http://sijmen.ruwhof.net/

  38. “That dodgy code was according to Google searches cited 322,300 times…”

    Just highlights the level of competence of our web developer community – don’t write code with care, copy and paste from demos without attention. Explains a lot about the deluge of breaches.

  39. A vulnerability in jQuery’s validation plugin was disclosed and patched this week. The problem was in a demo file that was included as a part of the captcha code and allowed for unchecked input from the user. I you have the jQuery valdiation plugin you should probably update or remove the problematic file.

  40. Vivek says:

    Hi Sijmen,
    That was a nice catch and you are not alone for the unexpected reply from jquery developers….
    I too have 2 critical vulnerability but no one is there to fixed it up 😛

Comments are closed.