From: Jonas Meurer <jonas@freesources.org>
Date: Mon, 20 May 2019 11:46:31 +0200
Subject: SA-CORE-2019-006

Origin: https://git.drupalcode.org/project/drupal/commit/d2f26902ef5d6de58caaf2a7c766eb2115b1c17e
Forwarded: not-needed
From: Alex Bronstein, Lee Rowlands, Jess, Lauri Eskola,
    Greg Knaddison, Neil Drumm, Samuel Mortenson
Date: Wed 17 Apr 2019 11:52:35 PM CDT
Subject: Fixes for SA-CORE-2019-006
 Backported the diff between 7.65 and 7.66, applying it to the version
 in the Stable Debian release (7.52).
 .
 The jQuery project released version 3.4.0, and as part of that,
 disclosed a security vulnerability that affects all prior
 versions. As described in their release notes:
 .
 jQuery 3.4.0 includes a fix for some unintended behavior when
 using jQuery.extend(true, {}, ...). If an unsanitized source
 object contained an enumerable __proto__ property, it could extend
 the native Object.prototype. This fix is included in jQuery 3.4.0,
 but patch diffs exist to patch previous jQuery versions.
 .
 It's possible that this vulnerability is exploitable with some Drupal
 modules. As a precaution, this Drupal security release backports the
 fix to jQuery.extend(), without making any other changes to the jQuery
 version that is included in Drupal core (3.2.1 for Drupal 8 and 1.4.4
 for Drupal 7) or running on the site via some other module such as
 jQuery Update.
 .
 The Drupal advisory is available in:
 .
 https://www.drupal.org/SA-CORE-2019-006
 .
 No CVE ID has yet been issued for this issue.
---
 misc/jquery-extend-3.4.0.js   | 112 ++++++++++++++++++++++++++++++++++++++++++
 modules/system/system.install |   7 +++
 modules/system/system.module  |   3 ++
 3 files changed, 122 insertions(+)
 create mode 100644 misc/jquery-extend-3.4.0.js

diff --git a/misc/jquery-extend-3.4.0.js b/misc/jquery-extend-3.4.0.js
new file mode 100644
index 0000000..9759109
--- /dev/null
+++ b/misc/jquery-extend-3.4.0.js
@@ -0,0 +1,112 @@
+/**
+ * For jQuery versions less than 3.4.0, this replaces the jQuery.extend
+ * function with the one from jQuery 3.4.0, slightly modified (documented
+ * below) to be compatible with older jQuery versions and browsers.
+ *
+ * This provides the Object.prototype pollution vulnerability fix to Drupal
+ * installations running older jQuery versions, including the versions shipped
+ * with Drupal core and https://www.drupal.org/project/jquery_update.
+ *
+ * @see https://github.com/jquery/jquery/pull/4333
+ */
+
+(function (jQuery) {
+
+// Do not override jQuery.extend() if the jQuery version is already >=3.4.0.
+var versionParts = jQuery.fn.jquery.split('.');
+var majorVersion = parseInt(versionParts[0]);
+var minorVersion = parseInt(versionParts[1]);
+var patchVersion = parseInt(versionParts[2]);
+var isPreReleaseVersion = (patchVersion.toString() !== versionParts[2]);
+if (
+  (majorVersion > 3) ||
+  (majorVersion === 3 && minorVersion > 4) ||
+  (majorVersion === 3 && minorVersion === 4 && patchVersion > 0) ||
+  (majorVersion === 3 && minorVersion === 4 && patchVersion === 0 && !isPreReleaseVersion)
+) {
+  return;
+}
+
+/**
+ * This is almost verbatim copied from jQuery 3.4.0.
+ *
+ * Only two minor changes have been made:
+ * - The call to isFunction() is changed to jQuery.isFunction().
+ * - The two calls to Array.isArray() is changed to jQuery.isArray().
+ *
+ * The above two changes ensure compatibility with all older jQuery versions
+ * (1.4.4 - 3.3.1) and older browser versions (e.g., IE8).
+ */
+jQuery.extend = jQuery.fn.extend = function() {
+  var options, name, src, copy, copyIsArray, clone,
+    target = arguments[ 0 ] || {},
+    i = 1,
+    length = arguments.length,
+    deep = false;
+
+  // Handle a deep copy situation
+  if ( typeof target === "boolean" ) {
+    deep = target;
+
+    // Skip the boolean and the target
+    target = arguments[ i ] || {};
+    i++;
+  }
+
+  // Handle case when target is a string or something (possible in deep copy)
+  if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
+    target = {};
+  }
+
+  // Extend jQuery itself if only one argument is passed
+  if ( i === length ) {
+    target = this;
+    i--;
+  }
+
+  for ( ; i < length; i++ ) {
+
+    // Only deal with non-null/undefined values
+    if ( ( options = arguments[ i ] ) != null ) {
+
+      // Extend the base object
+      for ( name in options ) {
+        copy = options[ name ];
+
+        // Prevent Object.prototype pollution
+        // Prevent never-ending loop
+        if ( name === "__proto__" || target === copy ) {
+          continue;
+        }
+
+        // Recurse if we're merging plain objects or arrays
+        if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
+          ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
+          src = target[ name ];
+
+          // Ensure proper type for the source value
+          if ( copyIsArray && !jQuery.isArray( src ) ) {
+            clone = [];
+          } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
+            clone = {};
+          } else {
+            clone = src;
+          }
+          copyIsArray = false;
+
+          // Never move original objects, clone them
+          target[ name ] = jQuery.extend( deep, clone, copy );
+
+          // Don't bring in undefined values
+        } else if ( copy !== undefined ) {
+          target[ name ] = copy;
+        }
+      }
+    }
+  }
+
+  // Return the modified object
+  return target;
+};
+
+})(jQuery);
diff --git a/modules/system/system.install b/modules/system/system.install
index 43c7383..2d4ea92 100644
--- a/modules/system/system.install
+++ b/modules/system/system.install
@@ -3150,6 +3150,13 @@ function system_update_7079() {
   db_change_field('file_managed', 'filesize', 'filesize', $spec);
 }
 
+/**
+ * Add 'jquery-extend-3.4.0.js' to the 'jquery' library.
+ */
+function system_update_7082() {
+  // Empty update to force a rebuild of hook_library() and JS aggregates.
+}
+
 /**
  * @} End of "defgroup updates-7.x-extra".
  * The next series of updates should start at 8000.
diff --git a/modules/system/system.module b/modules/system/system.module
index bf3f0a8..0003772 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -1176,6 +1176,9 @@ function system_library() {
     'version' => '1.4.4',
     'js' => array(
       'misc/jquery.js' => array('group' => JS_LIBRARY, 'weight' => -20),
+      // This includes a security fix, so assign a weight that makes this load
+      // as soon after jquery.js is loaded as possible.
+      'misc/jquery-extend-3.4.0.js' => array('group' => JS_LIBRARY, 'weight' => -19),
     ),
   );
 
