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
143 changes: 96 additions & 47 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,23 @@ 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>environment settings object</span>'s <span>origin</span>.</p></li>
recvfrom marked this conversation as resolved.
Show resolved Hide resolved

<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 +25589,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>

<li><p>Let <var>targetNavigable</var> be the first return value of applying <span>the rules for
recvfrom marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -25581,11 +25605,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 +60022,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 +89820,32 @@ 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>
<var>sourceDocument</var>, an <span>ordered map</span> <var>tokenizedFeatures</var>, a boolean
recvfrom marked this conversation as resolved.
Show resolved Hide resolved
<var>noreferrer</var>, and an optional <span>URL record</span> <var>url</var>, perform the
following steps. They return a boolean.</p>

<ol>
<li><p>If the <span>event loop</span>'s <span>termination nesting level</span> is nonzero,
return null.</p></li>
<li><p>If <var>noreferrer</var> is true, return true.</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>url</var> was given and <var>url</var>'s <span
data-x="concept-url-scheme">scheme</span> is "<code data-x="">blob</code>":</p>

<li><p>If <var>target</var> is the empty string, then set <var>target</var> to "<code
data-x="">_blank</code>".</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>environment settings object</span>'s <span>origin</span>.</p></li>
recvfrom marked this conversation as resolved.
Show resolved Hide resolved

<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>topLevelOrigin</var> be <var>sourceDocument</var>'s
<span>relevant settings object</span>'s <span>top-level origin</span>.</p></li>

<li><p>Let <var>noopener</var> and <var>noreferrer</var> be false.</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> 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,
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 @@ -89848,8 +89900,23 @@ dictionary <dfn dictionary>WindowPostMessageOptions</dfn> : <span>StructuredSeri

<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
<var>referrerPolicy</var> to "<code data-x="">no-referrer</code>".</p></li>
<li><p>If <var>noreferrer</var> is true, then set <var>referrerPolicy</var> to
"<code data-x="">no-referrer</code>".</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>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>noreferrer</var> if
<var>urlRecord</var> is failure; Otherwise, the result of <span
data-x="get noopener for window open">getting noopener for window open</span> with
<var>sourceDocument</var>, <var>tokenizedFeatures</var>, <var>noreferrer</var>, and
<var>urlRecord</var>.</p></li>
annevk marked this conversation as resolved.
Show resolved Hide resolved

<li>
<p>Let <var>targetNavigable</var> and <var>windowType</var> be the result of applying <span>the
Expand All @@ -89866,6 +89933,9 @@ dictionary <dfn dictionary>WindowPostMessageOptions</dfn> : <span>StructuredSeri

recvfrom marked this conversation as resolved.
Show resolved Hide resolved
<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>

<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 +89949,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 +89970,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