Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce noopener on cross-top-level-site Blob URLs #10731

Merged
merged 10 commits into from
Nov 18, 2024
135 changes: 90 additions & 45 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -25539,7 +25539,8 @@ document.body.appendChild(wbr);</code></pre>
web content.</p>

<p>To <dfn>get an element's noopener</dfn>, given an <code>a</code>, <code>area</code>, or
<code>form</code> element <var>element</var> and a string <var>target</var>:</p>
<code>form</code> element <var>element</var>, a <span>URL record</span> <var>url</var>, and a
string <var>target</var>, perform the following steps. They return a boolean.</p>

<ol>
<li><p>If <var>element</var>'s <a href="#linkTypes">link types</a> include the <code
Expand All @@ -25551,6 +25552,24 @@ document.body.appendChild(wbr);</code></pre>
<span>ASCII case-insensitive</span> match for "<code data-x="">_blank</code>", then return
true.</p></li>

<li>
<p>If <var>url</var>'s <span data-x="concept-url-scheme">scheme</span> is "<code
data-x="">blob</code>":</p>

recvfrom marked this conversation as resolved.
Show resolved Hide resolved
<ol>
<li><p>Let <var>blobOrigin</var> be <var>url</var>'s <span
recvfrom marked this conversation as resolved.
Show resolved Hide resolved
data-x="concept-url-blob-entry">blob URL entry</span>'s <span
data-x="blob-url-entry-environment">environment</span>'s <span
recvfrom marked this conversation as resolved.
Show resolved Hide resolved
data-x="concept-settings-object-origin">origin</span>.</p></li>

<li><p>Let <var>topLevelOrigin</var> be <var>element</var>'s <span>relevant settings
object</span>'s <span>top-level origin</span>.</p></li>

<li><p>If <var>blobOrigin</var> is not <span>same site</span> with <var>topLevelOrigin</var>,
then return true.</p></li>
</ol>
</li>

<li><p>Return false.</p></li>
</ol>

Expand All @@ -25571,8 +25590,14 @@ document.body.appendChild(wbr);</code></pre>
<var>targetAttributeValue</var> to the result of <span data-x="get an element's target">getting
an element's target</span> given <var>subject</var>.</p></li>

<li><p>Let <var>urlRecord</var> be the result of <span>encoding-parsing a URL</span> given
<var>subject</var>'s <code data-x="attr-hyperlink-href">href</code> attribute value, relative to
<var>subject</var>'s <span>node document</span>.</p></li>

<li><p>If <var>urlRecord</var> is failure, then return.</p></li>

<li><p>Let <var>noopener</var> be the result of <span data-x="get an element's noopener">getting
an element's noopener</span> with <var>subject</var> and
an element's noopener</span> with <var>subject</var>, <var>urlRecord</var>, and
<var>targetAttributeValue</var>.</p></li>

recvfrom marked this conversation as resolved.
Show resolved Hide resolved
<li><p>Let <var>targetNavigable</var> be the first return value of applying <span>the rules for
Expand All @@ -25581,11 +25606,8 @@ document.body.appendChild(wbr);</code></pre>

<li><p>If <var>targetNavigable</var> is null, then return.</p></li>

<li><p>Let <var>urlString</var> be the result of <span>encoding-parsing-and-serializing a
URL</span> given <var>subject</var>'s <code data-x="attr-hyperlink-href">href</code> attribute
value, relative to <var>subject</var>'s <span>node document</span>.</p></li>

<li><p>If <var>urlString</var> is failure, then return.</p></li>
<li><p>Let <var>urlString</var> be the result of applying the <span
data-x="concept-url-serializer">URL serializer</span> to <var>urlRecord</var>.</p></li>

<li><p>If <var>hyperlinkSuffix</var> is non-null, then append it to
<var>urlString</var>.</p></li>
Expand Down Expand Up @@ -60001,7 +60023,8 @@ fur
<var>formTarget</var>.</p></li>

<li><p>Let <var>noopener</var> be the result of <span data-x="get an element's noopener">getting
an element's noopener</span> with <var>form</var> and <var>target</var>.</p></li>
an element's noopener</span> with <var>form</var>, <var>parsed action</var>, and
<var>target</var>.</p></li>

<li><p>Let <var>targetNavigable</var> be the first return value of applying <span>the rules for
choosing a navigable</span> given <var>target</var>, <var>form</var>'s <span>node
Expand Down Expand Up @@ -89798,23 +89821,31 @@ dictionary <dfn dictionary>WindowPostMessageOptions</dfn> : <span>StructuredSeri

<div w-nodev>

<p>The <dfn>window open steps</dfn>, given a string <var>url</var>, a string <var>target</var>,
and a string <var>features</var>, are as follows:</p>
<p>To <dfn>get noopener for window open</dfn>, given a <span>Document</span>
recvfrom marked this conversation as resolved.
Show resolved Hide resolved
<var>sourceDocument</var>, an <span>ordered map</span> <var>tokenizedFeatures</var>, and a
<span>URL record</span> or failure <var>url</var>, perform the following steps. They return a
boolean.</p>

<ol>
recvfrom marked this conversation as resolved.
Show resolved Hide resolved
<li><p>If the <span>event loop</span>'s <span>termination nesting level</span> is nonzero,
return null.</p></li>
<li>
<p>If <var>url</var> is not failure and <var>url</var>'s <span
data-x="concept-url-scheme">scheme</span> is "<code data-x="">blob</code>":</p>

<li><p>Let <var>sourceDocument</var> be the <span>entry global object</span>'s <span
data-x="concept-document-window">associated <code>Document</code></span>.</p></li>
<ol>
<li><p>Let <var>blobOrigin</var> be <var>url</var>'s <span
data-x="concept-url-blob-entry">blob URL entry</span>'s <span
data-x="blob-url-entry-environment">environment</span>'s <span
data-x="concept-settings-object-origin">origin</span>.</p></li>
recvfrom marked this conversation as resolved.
Show resolved Hide resolved

<li><p>If <var>target</var> is the empty string, then set <var>target</var> to "<code
data-x="">_blank</code>".</p></li>
<li><p>Let <var>topLevelOrigin</var> be <var>sourceDocument</var>'s <span>relevant settings
object</span>'s <span>top-level origin</span>.</p></li>

<li><p>Let <var>tokenizedFeatures</var> be the result of <span
data-x="concept-window-open-features-tokenize">tokenizing</span> <var>features</var>.</p></li>
<li><p>If <var>blobOrigin</var>is not <span>same site</span> with <var>topLevelOrigin</var>,
then return true.</p></li>
</ol>
</li>

<li><p>Let <var>noopener</var> and <var>noreferrer</var> be false.</p></li>
<li><p>Let <var>noopener</var> be false.</p></li>

<li>
<p>If <var>tokenizedFeatures</var>["<code data-x="">noopener</code>"] <span data-x="map
recvfrom marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -89831,6 +89862,27 @@ dictionary <dfn dictionary>WindowPostMessageOptions</dfn> : <span>StructuredSeri
</ol>
</li>

<li><p>Return <var>noopener</var>.</p></li>
</ol>

<p>The <dfn>window open steps</dfn>, given a string <var>url</var>, a string <var>target</var>,
and a string <var>features</var>, are as follows:</p>

<ol>
<li><p>If the <span>event loop</span>'s <span>termination nesting level</span> is nonzero,
then return null.</p></li>
recvfrom marked this conversation as resolved.
Show resolved Hide resolved

<li><p>Let <var>sourceDocument</var> be the <span>entry global object</span>'s <span
data-x="concept-document-window">associated <code>Document</code></span>.</p></li>

<li><p>If <var>target</var> is the empty string, then set <var>target</var> to "<code
data-x="">_blank</code>".</p></li>

<li><p>Let <var>tokenizedFeatures</var> be the result of <span
data-x="concept-window-open-features-tokenize">tokenizing</span> <var>features</var>.</p></li>

<li><p>Let <var>noreferrer</var> be false.</p></li>

<li>
<p>If <var>tokenizedFeatures</var>["<code data-x="">noreferrer</code>"] <span data-x="map
exists">exists</span>, then:</p>
Expand All @@ -89846,6 +89898,17 @@ dictionary <dfn dictionary>WindowPostMessageOptions</dfn> : <span>StructuredSeri
</ol>
</li>

<li><p>Let <var>urlRecord</var> be the <span>URL record</span>
<code>about:blank</code>.</p></li>

<li><p>If <var>url</var> is not the empty string, then set <var>urlRecord</var> to the result
of <span>encoding-parsing a URL</span> given <var>url</var>, relative to the <span>entry
settings object</span>.</p></li>

<li><p>Let <var>noopener</var> be the result of <span
data-x="get noopener for window open">getting noopener for window open</span> with
<var>sourceDocument</var>, <var>tokenizedFeatures</var>, and <var>urlRecord</var>.</p></li>

<li><p>Let <var>referrerPolicy</var> be the empty string.</p></li>

<li><p>If <var>noreferrer</var> is true, then set <var>noopener</var> to true and set
Expand All @@ -89866,6 +89929,9 @@ dictionary <dfn dictionary>WindowPostMessageOptions</dfn> : <span>StructuredSeri

<li><p>If <var>targetNavigable</var> is null, then return null.</p></li>

<li><p>If <var>urlRecord</var> is failure, then throw a <span>"<code>SyntaxError</code>"</span>
<code>DOMException</code>.</p></li>
recvfrom marked this conversation as resolved.
Show resolved Hide resolved

<li>
<p>If <var>windowType</var> is either "<code data-x="">new and unrestricted</code>" or "<code
data-x="">new with no opener</code>", then:</p>
Expand All @@ -89879,16 +89945,6 @@ dictionary <dfn dictionary>WindowPostMessageOptions</dfn> : <span>StructuredSeri
data-x="nav-bc">active browsing context</span> given
<var>tokenizedFeatures</var>. <ref>CSSOMVIEW</ref></p></li>

<li><p>Let <var>urlRecord</var> be the <span>URL record</span>
<code>about:blank</code>.</p></li>

<li><p>If <var>url</var> is not the empty string, then set <var>urlRecord</var> to the result
of <span>encoding-parsing a URL</span> given <var>url</var>, relative to the <span>entry
settings object</span>.</p></li>

<li><p>If <var>urlRecord</var> is failure, then throw a <span>"<code>SyntaxError</code>"</span>
<code>DOMException</code>.</p></li>

<li>
<p>If <var>urlRecord</var> <span>matches <code>about:blank</code></span>, then perform the
<span>URL and history update steps</span> given <var>targetNavigable</var>'s <span
Expand All @@ -89910,22 +89966,11 @@ dictionary <dfn dictionary>WindowPostMessageOptions</dfn> : <span>StructuredSeri
<p>Otherwise:</p>

<ol>
<li>
<p>If <var>url</var> is not the empty string, then:</p>

<ol>
<li><p>Let <var>urlRecord</var> be the result of <span>encoding-parsing a URL</span>
<var>url</var>, relative to the <span>entry settings object</span>.</p></li>

<li><p>If <var>urlRecord</var> is failure, then throw a
<span>"<code>SyntaxError</code>"</span> <code>DOMException</code>.</p></li>

<li><p><span>Navigate</span><!--DONAV window.open()--> <var>targetNavigable</var> to
<var>urlRecord</var> using <var>sourceDocument</var>, with <i
data-x="navigation-referrer-policy">referrerPolicy</i> set to <var>referrerPolicy</var> and
<i><span>exceptionsEnabled</span></i> set to true.</p></li>
</ol>
</li>
<li><p>If <var>url</var> is not the empty string, then
<span>navigate</span><!--DONAV window.open()--> <var>targetNavigable</var> to
<var>urlRecord</var> using <var>sourceDocument</var>, with <i
data-x="navigation-referrer-policy">referrerPolicy</i> set to <var>referrerPolicy</var> and
<i><span>exceptionsEnabled</span></i> set to true.</p></li>

<li><p>If <var>noopener</var> is false, then set <var>targetNavigable</var>'s <span
data-x="nav-bc">active browsing context</span>'s <span>opener browsing context</span> to
Expand Down