Skip to content

fix all CVEs in 1.2.6 #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: 1.2.6-branch
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion component.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name" : "jquery",
"version" : "1.2.6",
"version" : "1.2.7-sec",
"main" : "./jquery.js",
"dependencies": {
}
Expand Down
33 changes: 12 additions & 21 deletions jquery.js
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
(function(){
/*
* jQuery 1.2.6 - New Wave Javascript
* jQuery 1.2.7-sec - New Wave Javascript
*
* Copyright (c) 2008 John Resig (jquery.com)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* $Date: 2008/05/26 $
* $Rev: 5685 $
* $Date$
* $Rev$
*/

// Map over jQuery in case of overwrite
Expand All @@ -21,8 +21,9 @@ var jQuery = window.jQuery = window.$ = function( selector, context ) {
};

// A simple way to check for HTML strings or ID strings
// (both of which we optimize for)
var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with <)
var quickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,

// Is it a simple selector
isSimple = /^.[^:#\[\.]*$/,
Expand Down Expand Up @@ -55,13 +56,13 @@ jQuery.fn = jQuery.prototype = {

// HANDLE: $("#id")
else {
var elem = document.getElementById( match[3] );
var elem = document.getElementById( match[2] );

// Make sure an element was located
if ( elem ){
// Handle the case where IE and Opera return items
// by name instead of ID
if ( elem.id != match[3] )
if ( elem.id != match[2] )
return jQuery().find( selector );

// Otherwise, we inject the element directly into the jQuery object
Expand All @@ -84,7 +85,7 @@ jQuery.fn = jQuery.prototype = {
},

// The current version of jQuery being used
jquery: "1.2.6",
jquery: "1.2.7-sec",

// The number of elements contained in the matched element set
size: function() {
Expand Down Expand Up @@ -576,8 +577,9 @@ jQuery.extend = jQuery.fn.extend = function() {
for ( var name in options ) {
var src = target[ name ], copy = options[ name ];

// Prevent Object.prototype pollution
// Prevent never-ending loop
if ( target === copy )
if ( name === "__proto__" || target === copy )
continue;

// Recurse if we're merging object values
Expand Down Expand Up @@ -952,21 +954,10 @@ jQuery.extend({

// Convert html string into DOM nodes
if ( typeof elem == "string" ) {
// Fix "XHTML"-style tags in all browsers
elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
all :
front + "></" + tag + ">";
});

// Trim whitespace, otherwise indexOf won't work as expected
var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");

var wrap =
// option or optgroup
!tags.indexOf("<opt") &&
[ 1, "<select multiple='multiple'>", "</select>" ] ||

!tags.indexOf("<leg") &&
[ 1, "<fieldset>", "</fieldset>" ] ||

Expand Down Expand Up @@ -2463,7 +2454,7 @@ jQuery.fn.extend({
jQuery("<div/>")
// inject the contents of the document in, removing the scripts
// to avoid any 'Permission Denied' errors in IE
.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
.append(res.responseText.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*< *\/ *script *>?/gi, ""))

// Locate the specified elements
.find(selector) :
Expand Down
2 changes: 1 addition & 1 deletion src/ajax.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jQuery.fn.extend({
jQuery("<div/>")
// inject the contents of the document in, removing the scripts
// to avoid any 'Permission Denied' errors in IE
.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
.append(res.responseText.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*< *\/ *script *>?/gi, ""))

// Locate the specified elements
.find(selector) :
Expand Down
23 changes: 7 additions & 16 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ var jQuery = window.jQuery = window.$ = function( selector, context ) {
};

// A simple way to check for HTML strings or ID strings
// (both of which we optimize for)
var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with <)
var quickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,

// Is it a simple selector
isSimple = /^.[^:#\[\.]*$/,
Expand Down Expand Up @@ -54,13 +55,13 @@ jQuery.fn = jQuery.prototype = {

// HANDLE: $("#id")
else {
var elem = document.getElementById( match[3] );
var elem = document.getElementById( match[2] );

// Make sure an element was located
if ( elem ){
// Handle the case where IE and Opera return items
// by name instead of ID
if ( elem.id != match[3] )
if ( elem.id != match[2] )
return jQuery().find( selector );

// Otherwise, we inject the element directly into the jQuery object
Expand Down Expand Up @@ -575,8 +576,9 @@ jQuery.extend = jQuery.fn.extend = function() {
for ( var name in options ) {
var src = target[ name ], copy = options[ name ];

// Prevent Object.prototype pollution
// Prevent never-ending loop
if ( target === copy )
if ( name === "__proto__" || target === copy )
continue;

// Recurse if we're merging object values
Expand Down Expand Up @@ -951,21 +953,10 @@ jQuery.extend({

// Convert html string into DOM nodes
if ( typeof elem == "string" ) {
// Fix "XHTML"-style tags in all browsers
elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
all :
front + "></" + tag + ">";
});

// Trim whitespace, otherwise indexOf won't work as expected
var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");

var wrap =
// option or optgroup
!tags.indexOf("<opt") &&
[ 1, "<select multiple='multiple'>", "</select>" ] ||

!tags.indexOf("<leg") &&
[ 1, "<fieldset>", "</fieldset>" ] ||

Expand Down
32 changes: 31 additions & 1 deletion test/unit/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ test("$()", function() {
equals( code.length, 1, "Correct number of elements generated for code" );
var img = $("<img/>");
equals( img.length, 1, "Correct number of elements generated for img" );
var div = $("<div/><hr/><code/><b/>");
var div = $("<div></div><hr><code></code><b></b>");
equals( div.length, 4, "Correct number of elements generated for div hr code b" );

// can actually yield more than one, when iframes are included, the window is an array as well
Expand Down Expand Up @@ -226,6 +226,29 @@ test("$('html', context)", function() {
equals($span.length, 1, "Verify a span created with a div context works, #1763");
});

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;
};

var $eCheck9521 = jQuery( '#<img id="check9521" src="no-such-.gif" onerror="jQuery._check9521(false)">' );

if($eCheck9521.length) {
$eCheck9521.appendTo("#main");
}
else {
jQuery._check9521(true);
}

start();

});

if ( !isLocal ) {
test("$(selector, xml).text(str) - Loaded via XML document", function() {
expect(2);
Expand Down Expand Up @@ -1393,6 +1416,13 @@ test("text(String)", function() {
equals( j[2].nodeType, 8, "Check node,textnode,comment with text()" );
});

test( "jQuery.extend( true, ... ) Object.prototype pollution", function( assert ) {
expect( 1 );

jQuery.extend( true, {}, JSON.parse( "{\"__proto__\": {\"devMode\": true}}" ) );
ok( !( "devMode" in {} ), "Object.prototype not polluted" );
} );

test("$.each(Object,Function)", function() {
expect(12);
$.each( [0,1,2], function(i, n){
Expand Down
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.2.6
1.2.7-sec