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

Commit

Permalink
Make the noreferrer option for window.open compatible with settin…
Browse files Browse the repository at this point in the history
…g `Cross-Origin-Opener-Policy: same-origin-allow-popups`

RELNOTES[INC]: The `noreferrer` option can no longer be set for modern browsers on sites that set a referrer-policy of `unsafe-url`

PiperOrigin-RevId: 400806976
Change-Id: I17c118281c4f62e2dc2529886fbdb2e1e6aa0fec
  • Loading branch information
Closure Team authored and copybara-github committed Oct 4, 2021
1 parent bb55f08 commit f2c85d1
Showing 1 changed file with 38 additions and 5 deletions.
43 changes: 38 additions & 5 deletions closure/goog/window/window.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,37 @@ goog.window.open = function(linkRef, opt_options, opt_parentWin) {
safeLinkRef = goog.html.SafeUrl.sanitize(url);
}

/** @suppress {strictMissingProperties} */
const browserSupportsCoop = self.crossOriginIsolation !== undefined;
let referrerPolicy = 'strict-origin-when-cross-origin';
if (window.Request) {
/** @suppress {missingProperties} */
referrerPolicy = new Request('/').referrerPolicy;
}
const pageSetsUnsafeReferrerPolicy = referrerPolicy === 'unsafe-url';

// Opening popups with `noreferrer` and a COOP policy of
// `same-origin-allow-popups` doesn't work. The below is a workaround
// for this browser limitation.
if (browserSupportsCoop && opt_options['noreferrer']) {
if (pageSetsUnsafeReferrerPolicy) {
// If the browser supports COOP, and the page explicitly sets a
// referrer-policy of `unsafe-url`, and the caller requests that the
// referrer is hidden, then things may break. We can't support the
// noreferrer option in this case, but ignoring it is potentially unsafe
// since the page is configured to expose the full URL. We just throw in
// this case so that callers can make a decision as to what they want to
// do here.
throw new Error(
'Cannot use the noreferrer option on a page that sets a referrer-policy of `unsafe-url` in modern browsers!');
}
// Any browser that supports COOP defaults to a referrer policy that hides
// the full URL. So we don't need to explicitly hide the referrer ourselves
// and can instead rely on the browser's default referrer policy to hide the
// referrer.
opt_options['noreferrer'] = false;
}

/** @suppress {missingProperties} loose references to 'target' */
/** @suppress {strictMissingProperties} */
var target = opt_options.target || linkRef.target;
Expand Down Expand Up @@ -208,7 +239,8 @@ goog.window.open = function(linkRef, opt_options, opt_parentWin) {
// do the wrong thing in only rare cases.
// ugh.
if (goog.string.contains(sanitizedLinkRef, ';')) {
sanitizedLinkRef = "'" + sanitizedLinkRef.replace(/'/g, '%27') + "'";
sanitizedLinkRef =
'\'' + sanitizedLinkRef.replace(/'/g, '%27') + '\'';
}
}
newWin.opener = null;
Expand Down Expand Up @@ -314,10 +346,11 @@ goog.window.openBlank = function(opt_message, opt_options, opt_parentWin) {
*
* (If your project is using GXPs, consider using {@link PopUpLink.gxp}.)
*
* @param {?goog.html.SafeUrl|string|?Object} linkRef If an Object with an 'href'
* attribute (such as HTMLAnchorElement) is passed then the value of 'href'
* is used, otherwise otherwise its toString method is called. Note that
* if a string|Object is used, it will be sanitized with SafeUrl.sanitize().
* @param {?goog.html.SafeUrl|string|?Object} linkRef If an Object with an
* 'href' attribute (such as HTMLAnchorElement) is passed then the value of
* 'href' is used, otherwise otherwise its toString method is called. Note
* that if a string|Object is used, it will be sanitized with
* SafeUrl.sanitize().
*
* @param {?Object=} opt_options Options to open window with.
* {@see goog.window.open for exact option semantics}
Expand Down

0 comments on commit f2c85d1

Please # to comment.