Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Showing with 20 additions and 2 deletions.
  1. +2 −2 src/core.js
  2. +18 −0 test/unit/core.js
4 src/core.js
@@ -16,8 +16,8 @@ var jQuery = function( selector, context ) {
// A simple way to check for HTML strings or ID strings
- // (both of which we optimize for)
- quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+ // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+ quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
// Check if a string has a non-whitespace character in it
rnotwhite = /\S/,
18 test/unit/core.js
@@ -467,6 +467,24 @@ test("isXMLDoc - HTML", function() {
document.body.removeChild( iframe );
+test("XSS via location.hash", function() {
+ expect(1);
+ stop();
+ jQuery._check9521 = function(x){
+ ok( x, "script called from #id-like selector with inline handler" );
+ jQuery("#check9521").remove();
+ delete jQuery._check9521;
+ start();
+ };
+ try {
+ // This throws an error because it's processed like an id
+ jQuery( '#<img id="check9521" src="no-such-.gif" onerror="jQuery._check9521(false)">' ).appendTo("#qunit-fixture");
+ } catch (err) {
+ jQuery._check9521(true);
+ };
if ( !isLocal ) {
test("isXMLDoc - XML", function() {

7 comments on commit db9e023


Hi dmethvin,

quickExpr = /^(?:\s*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/

is more better.

var user_input = "<img>"
$("a[class=" + user_input + "]") // create img element



Agreed but it is also more likely to cause a regression. For now I would like to stay with this patch, which only addresses the use of location.hash in $().


Why does quickExpr check for <tag> at all ?

Since a while now, $.fn.init checks something else, before it looks for quickExpr. The if statement that checks if .charAt(0) is < and the last character >, and if so, prepare for a HTML-match.

Afaik, there is no case were $() should accept HTML that doesn't start with < and ends with >. So, with the charAt-check for HTML in place, can't quickExpr be simplified to only match strings that start with a #, and pass on to document.getElementById ?

I'm probably missing something obvious here..


@Krinkle, it wouldn't surprise me if this code has gotten out of whack because of progressive changes. Could you open a ticket with your observations and reference this pull request? A patch and some more test cases would be good as well, maybe we can get this into 1.7.


threat is open for a while but "anything" discovered with #1.10.1 ?!


Not sure what you're asking about, but sure that this is the wrong place to ask.



Please sign in to comment.
Something went wrong with that request. Please try again.