Low watch CVSS 8.1 chrome Logic Error 🔧 Commit mapped

Overview

Low
Severity
8.1
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactCode injection in XML
DescriptionCode injection in XML
ComponentXML
Bug ClassLogic Error
Action tierwatch — logic/policy bug — security-relevant, no memory-unsafety
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker542115030
Fix commite83ada016b47 (chromium/src) +164/-8
CWECWE-94
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
CISA KEVNot listed
CreditedZabith Mohammed (@nmzabith)
Reported2026-08-03 (per vendor advisory)
Fix landed2026-09-01 (public git)
Disclosed2026-09-15
Patch gap14 days — fix public in source before the advisory

Background

"Already started" flag
a per-<script>-element flag defined by the HTML spec that, when set, makes the script inert so it will never execute even after being inserted into a live document.
XML scripting support disabled
a spec mode that requires script elements produced by an XML parse to be created with their “already started” flag set, so parsed scripts cannot run; it is mandated for both DOMParser.parseFromString and XMLHttpRequest.responseXML.
`CreateElementFlags`
the Blink parameter object passed into element creation whose SetAlreadyStarted(true) propagates the “already started” state onto newly created script elements at parse time.
`IsDOMParserDocument()` / `IsXHRDocument()`
Document predicates that identify whether a document was produced by DOMParser.parseFromString or by XMLHttpRequest.responseXML, respectively.

Root Cause Analysis

Blink parses XML through two backends, XMLDocumentParser (libxml2) in xml_document_parser.cc and XMLDocumentParserRs (Rust) in xml_document_parser_rs.cc, both of which build elements via a CreateElementFlags object at the element-creation site. Before the patch, that site set flags.SetAlreadyStarted(true) only when the feature was enabled AND document_->IsDOMParserDocument() was true AND the tag was an HTML or SVG script, so the “XML scripting support disabled” mode was applied only to DOMParser.parseFromString and not to XMLHttpRequest.responseXML. Because responseXML documents (IsXHRDocument()) never received the flag, script elements parsed out of an XHR XML/XHTML response were created without “already started” set and therefore remained live scripts. When such a script node was subsequently moved into the rendered document — directly, or via importNode, adoptNode, or cloneNode, all of which copy the flag — it would execute, violating the invariant that XML parsed with scripting support disabled yields inert scripts.

The fix consolidates the decision into ShouldMarkScriptAlreadyStarted(), which returns true for both IsDOMParserDocument() and IsXHRDocument(), so responseXML-parsed scripts are now marked inert at creation time and can no longer run.

Key insight
The single mistake was scoping the “already started” marking to DOMParser documents (and to script-tag matches) only, leaving XMLHttpRequest.responseXML scripts live; the fix replaces that narrow inline condition with ShouldMarkScriptAlreadyStarted(), which also covers IsXHRDocument(), restoring the spec-required inertness for both parse entry points.

Attack Path

  1. Deliver scripted XML via XHR A page issues an XMLHttpRequest for text/xml or application/xhtml+xml content (attacker-influenced, e.g. a server response or a data: URL) that contains a <script> element, and reads xhr.responseXML.
  2. Parser skips the inertness marking The XML backend creates the script element, but because the document is an XHR document rather than a DOMParser document, the pre-patch condition is false and SetAlreadyStarted(true) is never called, leaving the script “not started” and runnable.
  3. Script node is inserted into the live DOM The page appends the parsed node to document.body directly, or through importNode/adoptNode/cloneNode, each of which carries the (unset) “already started” flag onto the inserted node.
  4. Script executes On insertion into the live document the still-live script runs, injecting and executing attacker script in the page’s context (code injection). Escalation beyond in-context script execution is not demonstrated by the patch (inferred).

Impact Assessment

An attacker who controls the XML/XHTML body returned to an XMLHttpRequest.responseXML consumer can achieve script execution in the renderer/page context when that page moves a parsed script node into its live DOM, i.e. code injection in XML as the advisory titles it. The precondition is that the victim page fetch attacker-influenced XML via XHR and insert nodes from responseXML into a rendered document while relying on the spec guarantee that such scripts are inert. The vendor advisory rates this low severity and does not report in-the-wild exploitation; NVD scores it CVSS 8.1. Any escalation past in-context script execution is (inferred).

Files Changed

  • third_party/blink/renderer/core/xml/parser/xml_document_parser.h
  • third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html
  • third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html
  • third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.cc
  • third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
  • third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.h

Audit Directions

  • Divergent entry points to one parse routine
    Wherever a spec behavior (like “scripting support disabled”) must hold for several API entry points, audit that the shared parser applies it via a document-type predicate rather than an inline check keyed to only one caller such as IsDOMParserDocument().
  • Flag-at-creation invariants that survive node movement
    Review element-creation flags (e.g. “already started”) that must be set at parse time because they are copied by importNode/adoptNode/cloneNode; a missed set at creation cannot be recovered later and yields active nodes.
  • Duplicated logic across parser backends
    When two implementations exist (XMLDocumentParser and XMLDocumentParserRs), confirm every security-relevant condition is mirrored in both, since a fix or check applied to only one leaves the other exploitable.
From e83ada016b472defeff1ce6fbba96813c59a39ae Mon Sep 17 00:00:00 2001
From: Daniel Vogelheim <vogelheim@chromium.org>
Date: Tue, 01 Sep 2026 10:02:30 -0700
Subject: [PATCH] Consistently set XML parser "already started" flag.

The HTML spec & friends ask for XML parsing with
"XML scripting support disabled" in several instances, specifically for
DOMParser.parseFromString and XMLHttpResponse.responseXML.

Previously, this was only done for DOMParser.parseFromString. This
change also sets "already started" for XMLHttpResponse.responseXML.

In addition to the behavioural change above, we also simplify and unify
those two mechanisms:

- Move the decision into a separate method,
   ShouldMarkScriptAlreadyStarted, analogous to HTMLConstructionSite.
- Include spec links to justify their behaviour.
- Set CreateElementFlags for all elements, since CreateElement will
   read only the flag it needs, so there is no need to restrict it to
   scripts.
- We also add tests for the new cases.

Bug: 542115030, 540021703
Change-Id: I1b5e16fc63733b023d21cc3b5fd37b2c6b18f532
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8314690
Reviewed-by: David Baron <dbaron@chromium.org>
Commit-Queue: Daniel Vogelheim <vogelheim@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1689914}
---
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
index 004a812..52cee17b 100644
--- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
+++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
@@ -1227,10 +1227,7 @@
   CreateElementFlags flags =
       parsing_fragment_ ? CreateElementFlags::ByFragmentParser(document_)
                         : CreateElementFlags::ByParser(document_);
-  if (RuntimeEnabledFeatures::DOMParserXmlScriptAlreadyStartedEnabled() &&
-      document_->IsDOMParserDocument() &&
-      (q_name.Matches(html_names::kScriptTag) ||
-       q_name.Matches(svg_names::kScriptTag))) {
+  if (ShouldMarkScriptAlreadyStarted()) {
     flags.SetAlreadyStarted(true);
   }
 
@@ -1954,6 +1951,24 @@
   PauseParsing();
 }
 
+bool XMLDocumentParser::ShouldMarkScriptAlreadyStarted() const {
+  if (!RuntimeEnabledFeatures::DOMParserXmlScriptAlreadyStartedEnabled()) {
+    return false;
+  }
+
+  // The cases below parse XML documents with "XML scripting support disabled":
+  // See:
+  // https://html.spec.whatwg.org/multipage/xhtml.html#xml-scripting-support-disabled
+  return
+      // DOMParser.parseFromString parses with XML scripting support disabled:
+      // See: https://html.spec.whatwg.org/#dom-domparser-parsefromstring
+      //      step 3, "Otherwise", step 1.
+      document_->IsDOMParserDocument() ||
+      // XMLHTTPRequest.responseXML parses with XML scripting support disabled:
+      // See: https://xhr.spec.whatwg.org/#document-response, step 6
+      document_->IsXHRDocument();
+}
+
 void XMLDocumentParser::ExecuteScriptsWaitingForResources() {
   if (!IsWaitingForScripts() && !waiting_for_stylesheets_ && parser_paused_ &&
       IsParsing()) {
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.h b/third_party/blink/renderer/core/xml/parser/xml_document_parser.h
index 00d6e6f4..d6fa920c 100644
--- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.h
+++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.h
@@ -201,6 +201,8 @@
 
   void CheckIfBlockingStyleSheetAdded();
 
+  bool ShouldMarkScriptAlreadyStarted() const;
+
   SegmentedString original_source_for_transform_;
 
   xmlParserCtxtPtr Context() const {
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.cc
index 64c16076..5cc44bc9 100644
--- a/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.cc
+++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.cc
@@ -506,10 +506,7 @@
   CreateElementFlags flags =
       parsing_fragment_ ? CreateElementFlags::ByFragmentParser(document_)
                         : CreateElementFlags::ByParser(document_);
-  if (RuntimeEnabledFeatures::DOMParserXmlScriptAlreadyStartedEnabled() &&
-      document_->IsDOMParserDocument() &&
-      (q_name.Matches(html_names::kScriptTag) ||
-       q_name.Matches(svg_names::kScriptTag))) {
+  if (ShouldMarkScriptAlreadyStarted()) {
     flags.SetAlreadyStarted(true);
   }
 
@@ -843,6 +840,24 @@
   PauseParsing();
 }
 
+bool XMLDocumentParserRs::ShouldMarkScriptAlreadyStarted() const {
+  if (!RuntimeEnabledFeatures::DOMParserXmlScriptAlreadyStartedEnabled()) {
+    return false;
+  }
+
+  // The cases below parse XML documents with "XML scripting support disabled":
+  // See:
+  // https://html.spec.whatwg.org/multipage/xhtml.html#xml-scripting-support-disabled
+  return
+      // DOMParser.parseFromString parses with XML scripting support disabled:
+      // See: https://html.spec.whatwg.org/#dom-domparser-parsefromstring
+      //      step 3, "Otherwise", step 1.
+      document_->IsDOMParserDocument() ||
+      // XMLHTTPRequest.responseXML parses with XML scripting support disabled:
+      // See: https://xhr.spec.whatwg.org/#document-response, step 6
+      document_->IsXHRDocument();
+}
+
 void XMLDocumentParserRs::ExecuteScriptsWaitingForResources() {
   if (!IsWaitingForScripts() && !waiting_for_stylesheets_ && parser_paused_ &&
       IsParsing()) {
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.h b/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.h
index 1258c5c..b57e355d 100644
--- a/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.h
+++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.h
@@ -110,6 +110,8 @@
 
   void CheckIfBlockingStyleSheetAdded();
 
+  bool ShouldMarkScriptAlreadyStarted() const;
+
   Member<XMLParserScriptRunner> script_runner_;
   TextPosition script_start_position_;
   bool saw_error_ = false;
diff --git a/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html b/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html
index 6494ae5..22138a8 100644
--- a/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html
+++ b/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html
@@ -70,6 +70,57 @@
   document.body.appendChild(document.importNode(d.rootElement, true));
   assert_equals(window.mark, 0);
 }, "parseFromString as XML, svg script, append importNode result, but with namespace prefix");
+
+test(_ => {
+  window.mark = 0;
+  const d = new DOMParser().parseFromString(
+    "<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", "text/xml");
+  document.body.appendChild(document.adoptNode(d.rootElement));
+  assert_equals(window.mark, 0);
+}, "parseFromString as XML, svg script, append adoptNode result");
+
+test(_ => {
+  window.mark = 0;
+  const d = new DOMParser().parseFromString(
+    "<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", "text/xml");
+  document.body.appendChild(d.rootElement.cloneNode(true));
+  assert_equals(window.mark, 0);
+}, "parseFromString as XML, svg script, append cloneNode result");
+
+test(_ => {
+  window.mark = 0;
+  const d = new DOMParser().parseFromString(
+    "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml");
+  document.body.appendChild(document.importNode(d.documentElement, true));
+  assert_equals(window.mark, 0);
+}, "parseFromString as XHTML, whole root, append importNode result");
+
+test(_ => {
+  window.mark = 0;
+  const d = new DOMParser().parseFromString(
+    "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml");
+  const script = d.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+  document.body.appendChild(document.importNode(script, true));
+  assert_equals(window.mark, 0);
+}, "parseFromString as XHTML, script, append importNode result");
+
+test(_ => {
+  window.mark = 0;
+  const d = new DOMParser().parseFromString(
+    "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml");
+  const script = d.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+  document.body.appendChild(document.adoptNode(script));
+  assert_equals(window.mark, 0);
+}, "parseFromString as XHTML, script, append adoptNode result");
+
+test(_ => {
+  window.mark = 0;
+  const d = new DOMParser().parseFromString(
+    "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml");
+  const script = d.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+  document.body.appendChild(script.cloneNode(true));
+  assert_equals(window.mark, 0);
+}, "parseFromString as XHTML, script, append cloneNode result");
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html b/third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html
new file mode 100644
index 0000000..65a1903
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html
@@ -0,0 +1,71 @@
+<!doctype html>
+<html>
+<head>
+<title>XMLHttpRequest: script already started</title>
+<link rel="help" href="https://xhr.spec.whatwg.org/#document-response">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+// XMLHttpRequest.responseXML creates an XML parser with
+// XML scripting support disabled. This test tests that various
+// responseXML-parsed script elements are inactive ("already started").
+//
+// See:
+//   https://xhr.spec.whatwg.org/#document-response
+//   step 6, "with the XML scripting support disabled flag set."
+test(_ => {
+  window.mark = 0;
+  const xhr = new XMLHttpRequest();
+  xhr.open("GET", "data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", false);
+  xhr.send();
+  assert_not_equals(xhr.responseXML, null);
+  document.body.appendChild(xhr.responseXML.rootElement);
+  assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, svg script, appendChild");
+
+test(_ => {
+  window.mark = 0;
+  const xhr = new XMLHttpRequest();
+  xhr.open("GET", "data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", false);
+  xhr.send();
+  assert_not_equals(xhr.responseXML, null);
+  document.body.appendChild(document.importNode(xhr.responseXML.rootElement, true));
+  assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, svg script, append importNode result");
+
+test(_ => {
+  window.mark = 0;
+  const xhr = new XMLHttpRequest();
+  xhr.open("GET", "data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", false);
+  xhr.send();
+  assert_not_equals(xhr.responseXML, null);
+  document.body.appendChild(document.adoptNode(xhr.responseXML.rootElement));
+  assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, svg script, append adoptNode result");
+
+test(_ => {
+  window.mark = 0;
+  const xhr = new XMLHttpRequest();
+  xhr.open("GET", "data:application/xhtml+xml,<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", false);
+  xhr.send();
+  assert_not_equals(xhr.responseXML, null);
+  const script = xhr.responseXML.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+  document.body.appendChild(document.importNode(script, true));
+  assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, xhtml script, append importNode result");
+
+test(_ => {
+  window.mark = 0;
+  const xhr = new XMLHttpRequest();
+  xhr.open("GET", "data:application/xhtml+xml,<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", false);
+  xhr.send();
+  assert_not_equals(xhr.responseXML, null);
+  const script = xhr.responseXML.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+  document.body.appendChild(document.adoptNode(script));
+  assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, xhtml script, append adoptNode result");
+</script>
+</body>
+</html>
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html b/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html
index 6494ae5..22138a8 100644
--- a/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html
+++ b/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html
@@ -70,6 +70,57 @@
   document.body.appendChild(document.importNode(d.rootElement, true));
   assert_equals(window.mark, 0);
 }, "parseFromString as XML, svg script, append importNode result, but with namespace prefix");
+
+test(_ => {
+  window.mark = 0;
+  const d = new DOMParser().parseFromString(
+    "<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", "text/xml");
+  document.body.appendChild(document.adoptNode(d.rootElement));
+  assert_equals(window.mark, 0);
+}, "parseFromString as XML, svg script, append adoptNode result");
+
+test(_ => {
+  window.mark = 0;
+  const d = new DOMParser().parseFromString(
+    "<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", "text/xml");
+  document.body.appendChild(d.rootElement.cloneNode(true));
+  assert_equals(window.mark, 0);
+}, "parseFromString as XML, svg script, append cloneNode result");
+
+test(_ => {
+  window.mark = 0;
+  const d = new DOMParser().parseFromString(
+    "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml");
+  document.body.appendChild(document.importNode(d.documentElement, true));
+  assert_equals(window.mark, 0);
+}, "parseFromString as XHTML, whole root, append importNode result");
+
+test(_ => {
+  window.mark = 0;
+  const d = new DOMParser().parseFromString(
+    "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml");
+  const script = d.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+  document.body.appendChild(document.importNode(script, true));
+  assert_equals(window.mark, 0);
+}, "parseFromString as XHTML, script, append importNode result");
+
+test(_ => {
+  window.mark = 0;
+  const d = new DOMParser().parseFromString(
+    "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml");
+  const script = d.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+  document.body.appendChild(document.adoptNode(script));
+  assert_equals(window.mark, 0);
+}, "parseFromString as XHTML, script, append adoptNode result");
+
+test(_ => {
+  window.mark = 0;
+  const d = new DOMParser().parseFromString(
+    "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml");
+  const script = d.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+  document.body.appendChild(script.cloneNode(true));
+  assert_equals(window.mark, 0);
+}, "parseFromString as XHTML, script, append cloneNode result");
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html b/third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html
new file mode 100644
index 0000000..65a1903
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html
@@ -0,0 +1,71 @@
+<!doctype html>
+<html>
+<head>
+<title>XMLHttpRequest: script already started</title>
+<link rel="help" href="https://xhr.spec.whatwg.org/#document-response">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+// XMLHttpRequest.responseXML creates an XML parser with
+// XML scripting support disabled. This test tests that various
+// responseXML-parsed script elements are inactive ("already started").
+//
+// See:
+//   https://xhr.spec.whatwg.org/#document-response
+//   step 6, "with the XML scripting support disabled flag set."
+test(_ => {
+  window.mark = 0;
+  const xhr = new XMLHttpRequest();
+  xhr.open("GET", "data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", false);
+  xhr.send();
+  assert_not_equals(xhr.responseXML, null);
+  document.body.appendChild(xhr.responseXML.rootElement);
+  assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, svg script, appendChild");
+
+test(_ => {
+  window.mark = 0;
+  const xhr = new XMLHttpRequest();
+  xhr.open("GET", "data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", false);
+  xhr.send();
+  assert_not_equals(xhr.responseXML, null);
+  document.body.appendChild(document.importNode(xhr.responseXML.rootElement, true));
+  assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, svg script, append importNode result");
+
+test(_ => {
+  window.mark = 0;
+  const xhr = new XMLHttpRequest();
+  xhr.open("GET", "data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", false);
+  xhr.send();
+  assert_not_equals(xhr.responseXML, null);
+  document.body.appendChild(document.adoptNode(xhr.responseXML.rootElement));
+  assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, svg script, append adoptNode result");
+
+test(_ => {
+  window.mark = 0;
+  const xhr = new XMLHttpRequest();
+  xhr.open("GET", "data:application/xhtml+xml,<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", false);
+  xhr.send();
+  assert_not_equals(xhr.responseXML, null);
+  const script = xhr.responseXML.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+  document.body.appendChild(document.importNode(script, true));
+  assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, xhtml script, append importNode result");
+
+test(_ => {
+  window.mark = 0;
+  const xhr = new XMLHttpRequest();
+  xhr.open("GET", "data:application/xhtml+xml,<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", false);
+  xhr.send();
+  assert_not_equals(xhr.responseXML, null);
+  const script = xhr.responseXML.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+  document.body.appendChild(document.adoptNode(script));
+  assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, xhtml script, append adoptNode result");
+</script>
+</body>
+</html>
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.