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

Commit

Permalink
Improve compatibility when running under nonce-based Content Security…
Browse files Browse the repository at this point in the history
… Policies in base.js and test files.

RELNOTES: n/a

PiperOrigin-RevId: 329732703
  • Loading branch information
Closure Team authored and shicks committed Sep 3, 2020
1 parent 4e20faf commit 25db34e
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 21 deletions.
48 changes: 37 additions & 11 deletions closure/goog/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -2170,6 +2170,19 @@ goog.defineClass.applyProperties_ = function(target, source) {
// size also check for !COMPILED even though it redundant until this is fixed.
if (!COMPILED && goog.DEPENDENCIES_ENABLED) {

/**
* Returns the most recently added script element in the DOM.
* @return {?Element}
* @private
*/
goog.getLastScript_ = function() {
var elem = document.documentElement;
while (elem.nodeName != 'SCRIPT' && elem.lastChild) {
elem = elem.lastChild;
}
return /** @type {?Element} */ (elem);
};

/**
* Tries to detect whether is in the context of an HTML document.
* @return {boolean} True if it looks like HTML document.
Expand Down Expand Up @@ -3094,28 +3107,40 @@ if (!COMPILED && goog.DEPENDENCIES_ENABLED) {
}
}

var nonce = goog.getScriptNonce();
if (!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING &&
goog.isDocumentLoading_()) {
var allowInlineEventHandlers = !nonce;
var key = goog.Dependency.registerCallback_(function(script) {
if (!goog.DebugLoader_.IS_OLD_IE_ || script.readyState == 'complete') {
goog.Dependency.unregisterCallback_(key);
controller.loaded();
}
});
var nonceAttr = !goog.DebugLoader_.IS_OLD_IE_ && goog.getScriptNonce() ?
' nonce="' + goog.getScriptNonce() + '"' :
'';
var event =
var eventName =
goog.DebugLoader_.IS_OLD_IE_ ? 'onreadystatechange' : 'onload';
var defer = goog.Dependency.defer_ ? 'defer' : '';
var script = '<script src="' + this.path + '" ' + event +
'="goog.Dependency.callback_(\'' + key +
'\', this)" type="text/javascript" ' + defer + nonceAttr + '><' +
'/script>';
var event = '';
if (allowInlineEventHandlers) {
event = ' ' + eventName + '="goog.Dependency.callback_(\'' + key +
'\', this)"';
}

var defer = goog.Dependency.defer_ ? ' defer' : '';
var nonceAttr = nonce ? ' nonce="' + nonce + '"' : '';
var script = '<script src="' + this.path + '"' + nonceAttr + event +
defer + '><\/script>';

doc.write(
goog.TRUSTED_TYPES_POLICY_ ?
goog.TRUSTED_TYPES_POLICY_.createHTML(script) :
script);

if (!allowInlineEventHandlers) {
var elem = goog.getLastScript_();
elem.onload = /** @this {!HTMLScriptElement} */ function() {
goog.Dependency.callback_(key, this);
};
}
} else {
var scriptEl =
/** @type {!HTMLScriptElement} */ (doc.createElement('script'));
Expand All @@ -3125,7 +3150,6 @@ if (!COMPILED && goog.DEPENDENCIES_ENABLED) {

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

var script = '<script type="text/javascript">' +
var nonce = goog.getScriptNonce();
var nonceAttr = nonce ? ' nonce="' + nonce + '"' : '';
var script = '<script' + nonceAttr + '>' +
goog.protectScriptTag_('goog.Dependency.callback_("' + key + '");') +
'</' +
'script>';
Expand Down
5 changes: 3 additions & 2 deletions closure/goog/base_debug_loader_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -597,14 +597,15 @@ function testGoogRequireCheck() {

function testGetScriptNonce() {
// clear nonce cache for test.
const origNonce = goog.getScriptNonce();
goog.cspNonce_ = null;
const nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
const nonce = origNonce ? origNonce : 'ThisIsANonceThisIsANonceThisIsANonce';
const script = goog.dom.createElement(goog.dom.TagName.SCRIPT);
script.setAttribute('nonce', 'invalid nonce');
document.body.appendChild(script);

try {
assertEquals('', goog.getScriptNonce());
assertEquals(origNonce, goog.getScriptNonce());
// clear nonce cache for test.
goog.cspNonce_ = null;
script.nonce = nonce;
Expand Down
26 changes: 20 additions & 6 deletions closure/goog/dom/safe_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -676,11 +676,15 @@ testSuite({
this[attr] = value;
},
});
// clear nonce cache for test.
/** @type {?} */ (goog).cspNonce_ = null;
let nonce = goog.getScriptNonce();
if (!nonce) {
// clear nonce cache for test.
/** @type {?} */ (goog).cspNonce_ = null;

// Place a nonced script in the page.
nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
}

// Place a nonced script in the page.
const nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
const noncedScript = dom.createElement(TagName.SCRIPT);
noncedScript.setAttribute('nonce', nonce);
document.body.appendChild(noncedScript);
Expand Down Expand Up @@ -710,7 +714,11 @@ testSuite({
// clear nonce cache for test.
/** @type {?} */ (goog).cspNonce_ = null;
// create the iframe and set up a script inside the iframe.
const nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
let nonce = goog.getScriptNonce();
if (!nonce) {
nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
}

const iframe = dom.createElement(TagName.IFRAME);
document.body.appendChild(iframe);
const iframeWindow = iframe.contentWindow;
Expand Down Expand Up @@ -748,7 +756,13 @@ testSuite({
/** @type {?} */ (goog).cspNonce_ = null;

// Place a nonced script in the page.
const nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
let nonce = goog.getScriptNonce();
if (!nonce) {
nonce = 'ThisIsANonceThisIsANonceThisIsANonce';
}

/** @type {?} */ (goog).cspNonce_ = null;

const noncedScript = dom.createElement(TagName.SCRIPT);
noncedScript.setAttribute('nonce', nonce);
document.body.appendChild(noncedScript);
Expand Down
8 changes: 6 additions & 2 deletions closure/goog/net/jsonp_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,12 +299,16 @@ testSuite({
const checkCleanup = newCleanupGuard();

const jsonp = new Jsonp(fakeTrustedUrl);
jsonp.setNonce('foo');
let nonce = goog.getScriptNonce();
if (!nonce) {
nonce = 'foo';
}
jsonp.setNonce(nonce);
const result = jsonp.send();

const script = getScriptElement(result);
assertEquals(
'Nonce attribute should have been added to script element.', 'foo',
'Nonce attribute should have been added to script element.', nonce,
(script['nonce'] || script.getAttribute('nonce')));

checkCleanup();
Expand Down

0 comments on commit 25db34e

Please sign in to comment.