Skip to content
This repository was archived by the owner on Aug 1, 2024. It is now read-only.

Commit 25db34e

Browse files
Closure Teamshicks
authored andcommitted
Improve compatibility when running under nonce-based Content Security Policies in base.js and test files.
RELNOTES: n/a PiperOrigin-RevId: 329732703
1 parent 4e20faf commit 25db34e

File tree

4 files changed

+66
-21
lines changed

4 files changed

+66
-21
lines changed

closure/goog/base.js

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,6 +2170,19 @@ goog.defineClass.applyProperties_ = function(target, source) {
21702170
// size also check for !COMPILED even though it redundant until this is fixed.
21712171
if (!COMPILED && goog.DEPENDENCIES_ENABLED) {
21722172

2173+
/**
2174+
* Returns the most recently added script element in the DOM.
2175+
* @return {?Element}
2176+
* @private
2177+
*/
2178+
goog.getLastScript_ = function() {
2179+
var elem = document.documentElement;
2180+
while (elem.nodeName != 'SCRIPT' && elem.lastChild) {
2181+
elem = elem.lastChild;
2182+
}
2183+
return /** @type {?Element} */ (elem);
2184+
};
2185+
21732186
/**
21742187
* Tries to detect whether is in the context of an HTML document.
21752188
* @return {boolean} True if it looks like HTML document.
@@ -3094,28 +3107,40 @@ if (!COMPILED && goog.DEPENDENCIES_ENABLED) {
30943107
}
30953108
}
30963109

3110+
var nonce = goog.getScriptNonce();
30973111
if (!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING &&
30983112
goog.isDocumentLoading_()) {
3113+
var allowInlineEventHandlers = !nonce;
30993114
var key = goog.Dependency.registerCallback_(function(script) {
31003115
if (!goog.DebugLoader_.IS_OLD_IE_ || script.readyState == 'complete') {
31013116
goog.Dependency.unregisterCallback_(key);
31023117
controller.loaded();
31033118
}
31043119
});
3105-
var nonceAttr = !goog.DebugLoader_.IS_OLD_IE_ && goog.getScriptNonce() ?
3106-
' nonce="' + goog.getScriptNonce() + '"' :
3107-
'';
3108-
var event =
3120+
var eventName =
31093121
goog.DebugLoader_.IS_OLD_IE_ ? 'onreadystatechange' : 'onload';
3110-
var defer = goog.Dependency.defer_ ? 'defer' : '';
3111-
var script = '<script src="' + this.path + '" ' + event +
3112-
'="goog.Dependency.callback_(\'' + key +
3113-
'\', this)" type="text/javascript" ' + defer + nonceAttr + '><' +
3114-
'/script>';
3122+
var event = '';
3123+
if (allowInlineEventHandlers) {
3124+
event = ' ' + eventName + '="goog.Dependency.callback_(\'' + key +
3125+
'\', this)"';
3126+
}
3127+
3128+
var defer = goog.Dependency.defer_ ? ' defer' : '';
3129+
var nonceAttr = nonce ? ' nonce="' + nonce + '"' : '';
3130+
var script = '<script src="' + this.path + '"' + nonceAttr + event +
3131+
defer + '><\/script>';
3132+
31153133
doc.write(
31163134
goog.TRUSTED_TYPES_POLICY_ ?
31173135
goog.TRUSTED_TYPES_POLICY_.createHTML(script) :
31183136
script);
3137+
3138+
if (!allowInlineEventHandlers) {
3139+
var elem = goog.getLastScript_();
3140+
elem.onload = /** @this {!HTMLScriptElement} */ function() {
3141+
goog.Dependency.callback_(key, this);
3142+
};
3143+
}
31193144
} else {
31203145
var scriptEl =
31213146
/** @type {!HTMLScriptElement} */ (doc.createElement('script'));
@@ -3125,7 +3150,6 @@ if (!COMPILED && goog.DEPENDENCIES_ENABLED) {
31253150

31263151
// If CSP nonces are used, propagate them to dynamically created scripts.
31273152
// This is necessary to allow nonce-based CSPs without 'strict-dynamic'.
3128-
var nonce = goog.getScriptNonce();
31293153
if (nonce) {
31303154
scriptEl.setAttribute('nonce', nonce);
31313155
}
@@ -3428,7 +3452,9 @@ if (!COMPILED && goog.DEPENDENCIES_ENABLED) {
34283452
load();
34293453
});
34303454

3431-
var script = '<script type="text/javascript">' +
3455+
var nonce = goog.getScriptNonce();
3456+
var nonceAttr = nonce ? ' nonce="' + nonce + '"' : '';
3457+
var script = '<script' + nonceAttr + '>' +
34323458
goog.protectScriptTag_('goog.Dependency.callback_("' + key + '");') +
34333459
'</' +
34343460
'script>';

closure/goog/base_debug_loader_test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -597,14 +597,15 @@ function testGoogRequireCheck() {
597597

598598
function testGetScriptNonce() {
599599
// clear nonce cache for test.
600+
const origNonce = goog.getScriptNonce();
600601
goog.cspNonce_ = null;
601-
const nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
602+
const nonce = origNonce ? origNonce : 'ThisIsANonceThisIsANonceThisIsANonce';
602603
const script = goog.dom.createElement(goog.dom.TagName.SCRIPT);
603604
script.setAttribute('nonce', 'invalid nonce');
604605
document.body.appendChild(script);
605606

606607
try {
607-
assertEquals('', goog.getScriptNonce());
608+
assertEquals(origNonce, goog.getScriptNonce());
608609
// clear nonce cache for test.
609610
goog.cspNonce_ = null;
610611
script.nonce = nonce;

closure/goog/dom/safe_test.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -676,11 +676,15 @@ testSuite({
676676
this[attr] = value;
677677
},
678678
});
679-
// clear nonce cache for test.
680-
/** @type {?} */ (goog).cspNonce_ = null;
679+
let nonce = goog.getScriptNonce();
680+
if (!nonce) {
681+
// clear nonce cache for test.
682+
/** @type {?} */ (goog).cspNonce_ = null;
683+
684+
// Place a nonced script in the page.
685+
nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
686+
}
681687

682-
// Place a nonced script in the page.
683-
const nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
684688
const noncedScript = dom.createElement(TagName.SCRIPT);
685689
noncedScript.setAttribute('nonce', nonce);
686690
document.body.appendChild(noncedScript);
@@ -710,7 +714,11 @@ testSuite({
710714
// clear nonce cache for test.
711715
/** @type {?} */ (goog).cspNonce_ = null;
712716
// create the iframe and set up a script inside the iframe.
713-
const nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
717+
let nonce = goog.getScriptNonce();
718+
if (!nonce) {
719+
nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
720+
}
721+
714722
const iframe = dom.createElement(TagName.IFRAME);
715723
document.body.appendChild(iframe);
716724
const iframeWindow = iframe.contentWindow;
@@ -748,7 +756,13 @@ testSuite({
748756
/** @type {?} */ (goog).cspNonce_ = null;
749757

750758
// Place a nonced script in the page.
751-
const nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
759+
let nonce = goog.getScriptNonce();
760+
if (!nonce) {
761+
nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
762+
}
763+
764+
/** @type {?} */ (goog).cspNonce_ = null;
765+
752766
const noncedScript = dom.createElement(TagName.SCRIPT);
753767
noncedScript.setAttribute('nonce', nonce);
754768
document.body.appendChild(noncedScript);

closure/goog/net/jsonp_test.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,12 +299,16 @@ testSuite({
299299
const checkCleanup = newCleanupGuard();
300300

301301
const jsonp = new Jsonp(fakeTrustedUrl);
302-
jsonp.setNonce('foo');
302+
let nonce = goog.getScriptNonce();
303+
if (!nonce) {
304+
nonce = 'foo';
305+
}
306+
jsonp.setNonce(nonce);
303307
const result = jsonp.send();
304308

305309
const script = getScriptElement(result);
306310
assertEquals(
307-
'Nonce attribute should have been added to script element.', 'foo',
311+
'Nonce attribute should have been added to script element.', nonce,
308312
(script['nonce'] || script.getAttribute('nonce')));
309313

310314
checkCleanup();

0 commit comments

Comments
 (0)