From 005040379d8b64aacbe54941d878efa6e86df1cc Mon Sep 17 00:00:00 2001 From: buddh4 Date: Tue, 19 Mar 2019 22:40:30 +0100 Subject: [PATCH] Core: Preserve CSP nonce on scripts with src attribute in DOM manipulation Fixes gh-4323 Closes gh-4328 --- src/manipulation.js | 4 +++- src/manipulation/_evalUrl.js | 4 ++-- test/data/csp-nonce-external.html | 13 +++++++++++++ test/data/csp-nonce-external.js | 5 +++++ test/unit/manipulation.js | 23 +++++++++++++++++++++++ 5 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 test/data/csp-nonce-external.html create mode 100644 test/data/csp-nonce-external.js diff --git a/src/manipulation.js b/src/manipulation.js index 7dbc92689..ab19d8b3c 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -199,7 +199,9 @@ function domManip( collection, args, callback, ignored ) { // Optional AJAX dependency, but won't run scripts if not present if ( jQuery._evalUrl && !node.noModule ) { - jQuery._evalUrl( node.src ); + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + } ); } } else { DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); diff --git a/src/manipulation/_evalUrl.js b/src/manipulation/_evalUrl.js index e20995a89..9a4d2ac6f 100644 --- a/src/manipulation/_evalUrl.js +++ b/src/manipulation/_evalUrl.js @@ -4,7 +4,7 @@ define( [ "use strict"; -jQuery._evalUrl = function( url ) { +jQuery._evalUrl = function( url, options ) { return jQuery.ajax( { url: url, @@ -22,7 +22,7 @@ jQuery._evalUrl = function( url ) { "text script": function() {} }, dataFilter: function( response ) { - jQuery.globalEval( response ); + jQuery.globalEval( response, options ); } } ); }; diff --git a/test/data/csp-nonce-external.html b/test/data/csp-nonce-external.html new file mode 100644 index 000000000..8baa85c75 --- /dev/null +++ b/test/data/csp-nonce-external.html @@ -0,0 +1,13 @@ + + + + + CSP nonce via jQuery.globalEval Test Page + + + + + +

CSP nonce for external script Test Page

+ + diff --git a/test/data/csp-nonce-external.js b/test/data/csp-nonce-external.js new file mode 100644 index 000000000..efedd5a9a --- /dev/null +++ b/test/data/csp-nonce-external.js @@ -0,0 +1,5 @@ +/* global startIframeTest */ + +jQuery( function() { + $( "body" ).append( "" ); +} ); diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index d8c86e31c..b0d3e3a88 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -2894,6 +2894,29 @@ testIframe( QUnit[ /\bedge\/|iphone os [789]|android 4\./i.test( navigator.userAgent ) ? "skip" : "test" ] ); +testIframe( + "Check if CSP nonce is preserved for external scripts with src attribute", + "mock.php?action=cspNonce&test=external", + function( assert, jQuery, window, document ) { + var done = assert.async(); + + assert.expect( 1 ); + + supportjQuery.get( baseURL + "support/csp.log" ).done( function( data ) { + assert.equal( data, "", "No log request should be sent" ); + supportjQuery.get( baseURL + "mock.php?action=cspClean" ).done( done ); + } ); + }, + + // Support: Edge 18+, iOS 7-9 only, Android 4.0-4.4 only + // Edge doesn't support nonce in non-inline scripts. + // See https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/13246371/ + // Old iOS & Android Browser versions support script-src but not nonce, making this test + // impossible to run. Browsers not supporting CSP at all are not a problem as they'll skip + // script-src restrictions completely. + QUnit[ /\bedge\/|iphone os [789]|android 4\./i.test( navigator.userAgent ) ? "skip" : "test" ] +); + testIframe( "jQuery.globalEval supports nonce", "mock.php?action=cspNonce&test=globaleval",