@lwrjs/client-modules 0.23.5 → 0.23.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -590,6 +590,7 @@ const {
590
590
  substring: StringProtoSubstring$LWS,
591
591
  toLowerCase: StringProtoToLowerCase$LWS,
592
592
  toUpperCase: StringProtoToUpperCase$LWS,
593
+ trim: StringProtoTrim$LWS,
593
594
  valueOf: StringProtoValueOf$LWS$1
594
595
  } = StringProto$LWS$1;
595
596
  const quoteCharRegExpRegistry$LWS = {
@@ -1510,7 +1511,7 @@ const {
1510
1511
  const PromiseResolve$LWS = PromiseCtor$LWS.resolve.bind(PromiseCtor$LWS);
1511
1512
  const PromiseReject$LWS = PromiseCtor$LWS.reject.bind(PromiseCtor$LWS);
1512
1513
  const trustedResources$LWS = toSafeSet$LWS(new SetCtor$LWS$1());
1513
- /*! version: 0.28.1 */
1514
+ /*! version: 0.28.3 */
1514
1515
 
1515
1516
  /*!
1516
1517
  * Copyright (C) 2019 salesforce.com, inc.
@@ -1553,6 +1554,8 @@ const {
1553
1554
  open: DocumentProtoOpen$LWS$1
1554
1555
  } = DocumentProto$LWS$1;
1555
1556
  const {
1557
+ createAttribute: DocumentProtoCreateAttribute$LWS,
1558
+ createAttributeNS: DocumentProtoCreateAttributeNS$LWS,
1556
1559
  createComment: DocumentProtoCreateComment$LWS,
1557
1560
  createDocumentFragment: DocumentProtoCreateDocumentFragment$LWS,
1558
1561
  createElement: DocumentProtoCreateElement$LWS$1,
@@ -1578,6 +1581,13 @@ const {
1578
1581
  // - noopener=1
1579
1582
  // - noopener=yes
1580
1583
  const noopenerRegExp$LWS = /(^|,)(\s*noopener\s*=\s*(?:yes|1)\s*)(,|$)/g;
1584
+ // Detects whether a (lowercased) features string contains any form of "noopener",
1585
+ // including bare "noopener", "noopener=yes", "noopener=1", etc.
1586
+ // Used by the window.open distortion to avoid double-injection.
1587
+ const noopenerPresentRegExp$LWS = /(^|,)\s*noopener\s*(=\s*[^,]*)?\s*(,|$)/;
1588
+ function isNoopenerPresent$LWS(lowercasedFeatures$LWS) {
1589
+ return ReflectApply$LWS$1(RegExpProtoTest$LWS$1, noopenerPresentRegExp$LWS, [lowercasedFeatures$LWS]);
1590
+ }
1581
1591
  const rootWindow$LWS$1 = window;
1582
1592
  // These properties are part of the WindowOrGlobalScope mixin and not on
1583
1593
  // Window.prototype.
@@ -1910,6 +1920,16 @@ const HTMLElementGlobalAttributesToPropertyName$LWS = {
1910
1920
  inputmode: 'inputMode',
1911
1921
  tabindex: 'tabIndex'
1912
1922
  };
1923
+ const {
1924
+ prototype: HTMLIFrameElementProto$LWS
1925
+ } = HTMLIFrameElement;
1926
+ // Used by '@locker/near-membrane-dom'.
1927
+ ObjectLookupOwnGetter$LWS$1(HTMLIFrameElementProto$LWS, 'contentWindow');
1928
+ const HTMLIFrameElementProtoSandboxGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLIFrameElementProto$LWS, 'sandbox');
1929
+ const HTMLIFrameElementProtoSandboxSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLIFrameElementProto$LWS, 'sandbox');
1930
+ const HTMLIFrameElementProtoSrcGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLIFrameElementProto$LWS, 'src');
1931
+ const HTMLIFrameElementProtoSrcSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLIFrameElementProto$LWS, 'src');
1932
+ const HTMLIFrameElementProtoSrcdocGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLIFrameElementProto$LWS, 'srcdoc');
1913
1933
  const HTMLTemplateElementProtoContentGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLTemplateElement.prototype, 'content');
1914
1934
  const {
1915
1935
  prototype: NodeProto$LWS$1
@@ -1994,24 +2014,52 @@ class Validator$LWS {
1994
2014
  const normalizedInput$LWS = normalizeInput$LWS(input$LWS);
1995
2015
  return hasTag$LWS(normalizedInput$LWS, 'script') && ReflectApply$LWS$1(StringProtoIncludes$LWS, normalizedInput$LWS, ['xmlns']);
1996
2016
  };
1997
- // There is no reason to ever allow any HTML or XML that contains all three of these substrings.
2017
+ // Detects the iframe+srcdoc substring combination in raw input.
2018
+ // Any HTML or XML containing both <iframe> and the substring
2019
+ // 'srcdoc' is considered hostile, regardless of where the
2020
+ // substrings appear (markup, attribute value, script string
2021
+ // literal, etc.). Sufficient by itself: scanners that rely on
2022
+ // splitting an attacker-supplied iframe+srcdoc into separate
2023
+ // tokens (e.g. via DOM-mutation tricks or string concatenation
2024
+ // at runtime) cannot evade a pure substring check on the served
2025
+ // body. Cheap (no DOM parse), safe to call on any iframe.src body
2026
+ // in particular, where bodies routinely contain legitimate
2027
+ // <script> elements but never need to embed a child iframe with
2028
+ // srcdoc.
1998
2029
  // eslint-disable-next-line class-methods-use-this
2030
+ this.isIframeSrcdocAttack = input$LWS => {
2031
+ const normalizedInput$LWS = normalizeInput$LWS(input$LWS);
2032
+ return hasTag$LWS(normalizedInput$LWS, 'iframe') && ReflectApply$LWS$1(StringProtoIncludes$LWS, normalizedInput$LWS, ['srcdoc']);
2033
+ };
2034
+ // Detects (a) the iframe+srcdoc substring combination, OR (b) a
2035
+ // hidden <script> element — markup whose innerHTML contains a
2036
+ // script tag while innerText does not, indicating the script was
2037
+ // obfuscated to evade a sanitizer's text-level inspection.
2038
+ // Suitable for HTML-handling APIs (innerHTML, setHTMLUnsafe,
2039
+ // outerHTML, DOMParser, etc.) that should never accept any
2040
+ // <script>-bearing input from sandboxed code.
2041
+ //
2042
+ // NOT suitable for iframe.src body inspection: existing test
2043
+ // fixtures and component code rely on iframe.src loading same-
2044
+ // origin pages that contain <script> elements (legacy contract
2045
+ // we are stuck with — the iframe sandbox is the layer that
2046
+ // contains their execution). The path-2 obfuscated-script check
2047
+ // would reject those bodies and break the contract. For iframe.src
2048
+ // body inspection use `isIframeSrcdocAttack` instead, which covers
2049
+ // only the path-1 substring check.
1999
2050
  this.isIframeSrcdocScriptAttack = input$LWS => {
2051
+ if (this.isIframeSrcdocAttack(input$LWS)) {
2052
+ return true;
2053
+ }
2000
2054
  const normalizedInput$LWS = normalizeInput$LWS(input$LWS);
2001
- const hasIframe$LWS = hasTag$LWS(normalizedInput$LWS, 'iframe') && ReflectApply$LWS$1(StringProtoIncludes$LWS, normalizedInput$LWS, ['srcdoc']);
2002
2055
  const hasScript$LWS = hasTag$LWS(normalizedInput$LWS, 'script');
2003
- // If neither an iframe or a script was detected, then this input is safe.
2056
+ // If no script was detected, the input is safe.
2004
2057
  // istanbul ignore else: returns immediately
2005
- if (!hasIframe$LWS && !hasScript$LWS) {
2058
+ if (!hasScript$LWS) {
2006
2059
  return false;
2007
2060
  }
2008
- // If the string contains both the words iframe and srcdoc, it is unsafe
2009
- // istanbul ignore else: returns immediately
2010
- if (hasIframe$LWS) {
2011
- return true;
2012
- }
2013
2061
  // This is obnoxious... jsdom doesn't implement HTMLElement.prototype.innerText
2014
- if (!HTMLElementProtoInnerTextGetter$LWS && hasScript$LWS) {
2062
+ if (!HTMLElementProtoInnerTextGetter$LWS) {
2015
2063
  return true;
2016
2064
  }
2017
2065
  // If the input contained the word "script", then we need to confirm that the string
@@ -2039,6 +2087,64 @@ class Validator$LWS {
2039
2087
  return hasTag$LWS(innerHTML$LWS, 'script') && !hasTag$LWS(checkableInnerText$LWS, 'script');
2040
2088
  };
2041
2089
  this.isSharedElement = element$LWS => element$LWS === ReflectApply$LWS$1(DocumentProtoHeadGetter$LWS, this._document, []) || element$LWS === ReflectApply$LWS$1(DocumentProtoBodyGetter$LWS$1, this._document, []) || element$LWS === ReflectApply$LWS$1(DocumentProtoDocumentElementGetter$LWS, this._document, []);
2090
+ // Detects whether `node` belongs to a document that an attacker
2091
+ // could have populated with content bypassing LWS distortions.
2092
+ // Used to gate cross-document node-movement APIs (Document.adoptNode,
2093
+ // Document.importNode) against the W-22382462 chain shape.
2094
+ //
2095
+ // Returns true when the source document's browsing context is
2096
+ // wrapped in an iframe loaded from a non-blank URL or carrying a
2097
+ // `srcdoc` attribute. In those cases the document was loaded
2098
+ // through the browser's native parser (HTML or XML); for XHTML
2099
+ // resources, that includes DOCTYPE/ATTLIST processing that runs
2100
+ // below the JS layer where no LWS distortion can intercept it.
2101
+ //
2102
+ // Returns false (benign) for:
2103
+ // - Same-document operations (`node.ownerDocument === currentDocument`).
2104
+ // - Detached documents (`defaultView === null`) — created via
2105
+ // `document.implementation.createHTMLDocument()` or
2106
+ // `DOMParser.parseFromString()`. These have no browsing context
2107
+ // and can only be populated via prototype-distorted APIs that
2108
+ // LWS already validates at insertion time.
2109
+ // - Documents hosted by the sandbox's own host window
2110
+ // (`defaultView === rootWindow`). LWS itself runs sandboxed
2111
+ // code inside a bootstrap iframe whose `src` is non-blank, so
2112
+ // the sandbox's view of `document` would otherwise be
2113
+ // unconditionally refused. The sandbox's own host iframe is
2114
+ // not user-controlled.
2115
+ // - Top-level documents (`defaultView.frameElement === null`).
2116
+ // - Iframe-hosted documents whose iframe has empty/about:blank
2117
+ // `src` AND empty `srcdoc` — never loaded a network resource.
2118
+ // eslint-disable-next-line class-methods-use-this
2119
+ this.isAttackerOwnedNode = (node$LWS, currentDocument$LWS) => {
2120
+ const sourceDocument$LWS = ReflectApply$LWS$1(NodeProtoOwnerDocumentGetter$LWS, node$LWS, []);
2121
+ if (sourceDocument$LWS === null || sourceDocument$LWS === currentDocument$LWS) {
2122
+ return false;
2123
+ }
2124
+ const view$LWS = ReflectApply$LWS$1(DocumentProtoDefaultViewGetter$LWS, sourceDocument$LWS, []);
2125
+ if (view$LWS === null || view$LWS === rootWindow$LWS$1) {
2126
+ return false;
2127
+ }
2128
+ const frame$LWS = ReflectApply$LWS$1(WindowFrameElementGetter$LWS, view$LWS, []);
2129
+ if (frame$LWS === null) {
2130
+ return false;
2131
+ }
2132
+ if (frame$LWS instanceof HTMLIFrameElement) {
2133
+ const src$LWS = ReflectApply$LWS$1(HTMLIFrameElementProtoSrcGetter$LWS, frame$LWS, []);
2134
+ if (src$LWS !== '' && src$LWS !== 'about:blank') {
2135
+ return true;
2136
+ }
2137
+ const srcdoc$LWS = ReflectApply$LWS$1(HTMLIFrameElementProtoSrcdocGetter$LWS, frame$LWS, []);
2138
+ if (srcdoc$LWS) {
2139
+ return true;
2140
+ }
2141
+ return false;
2142
+ }
2143
+ // Other frame-hosting elements (HTMLFrameElement, HTMLObjectElement)
2144
+ // can carry network-loaded documents too. Conservative posture:
2145
+ // refuse, since these are uncommon legitimate ownership chains.
2146
+ return true;
2147
+ };
2042
2148
  this._constructors = {
2043
2149
  HTMLLinkElement: HTMLLinkElement$LWS,
2044
2150
  HTMLScriptElement: HTMLScriptElement$LWS,
@@ -2124,10 +2230,13 @@ const {
2124
2230
  const {
2125
2231
  add: DOMTokenListProtoAdd$LWS,
2126
2232
  contains: DOMTokenListProtoContains$LWS,
2127
- remove: DOMTokenListProtoRemove$LWS
2233
+ remove: DOMTokenListProtoRemove$LWS,
2234
+ replace: DOMTokenListProtoReplace$LWS,
2235
+ toggle: DOMTokenListProtoToggle$LWS
2128
2236
  } = DOMTokenListProto$LWS;
2129
2237
  const DOMTokenListProtoLengthGetter$LWS = ObjectLookupOwnGetter$LWS$1(DOMTokenListProto$LWS, 'length');
2130
2238
  const DOMTokenListProtoValueGetter$LWS = ObjectLookupOwnGetter$LWS$1(DOMTokenListProto$LWS, 'value');
2239
+ const DOMTokenListProtoValueSetter$LWS = ObjectLookupOwnSetter$LWS(DOMTokenListProto$LWS, 'value');
2131
2240
  const EventCtor$LWS = Event;
2132
2241
  const {
2133
2242
  prototype: EventProto$LWS
@@ -2136,6 +2245,7 @@ const {
2136
2245
  stopPropagation: EventProtoStopPropagation$LWS
2137
2246
  } = EventProto$LWS;
2138
2247
  const EventProtoCurrentTargetGetter$LWS = ObjectLookupOwnGetter$LWS$1(EventProto$LWS, 'currentTarget');
2248
+ const EventProtoTypeGetter$LWS = ObjectLookupOwnGetter$LWS$1(EventProto$LWS, 'type');
2139
2249
  const {
2140
2250
  addEventListener: EventTargetProtoAddEventListener$LWS,
2141
2251
  dispatchEvent: EventTargetProtoDispatchEvent$LWS,
@@ -2151,6 +2261,7 @@ const {
2151
2261
  } = ReflectGetOwnPropertyDescriptor$LWS(HTMLAnchorElementProto$LWS, 'href');
2152
2262
  const HTMLAnchorElementProtoPathnameGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLAnchorElementProto$LWS, 'pathname');
2153
2263
  const HTMLAnchorElementProtoProtocolGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLAnchorElementProto$LWS, 'protocol');
2264
+ const HTMLAnchorElementProtoProtocolSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLAnchorElementProto$LWS, 'protocol');
2154
2265
  const {
2155
2266
  prototype: HTMLButtonElementProto$LWS
2156
2267
  } = HTMLButtonElement;
@@ -2166,14 +2277,10 @@ const {
2166
2277
  set: HTMLFormElementProtoActionSetter$LWS
2167
2278
  } = ReflectGetOwnPropertyDescriptor$LWS(HTMLFormElementProto$LWS, 'action');
2168
2279
  const {
2169
- prototype: HTMLIFrameElementProto$LWS
2170
- } = HTMLIFrameElement;
2171
- // Used by '@locker/near-membrane-dom'.
2172
- ObjectLookupOwnGetter$LWS$1(HTMLIFrameElementProto$LWS, 'contentWindow');
2173
- const HTMLIFrameElementProtoSandboxGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLIFrameElementProto$LWS, 'sandbox');
2174
- const HTMLIFrameElementProtoSandboxSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLIFrameElementProto$LWS, 'sandbox');
2175
- const HTMLIFrameElementProtoSrcGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLIFrameElementProto$LWS, 'src');
2176
- const HTMLIFrameElementProtoSrcSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLIFrameElementProto$LWS, 'src');
2280
+ prototype: HTMLImageElementProto$LWS
2281
+ } = HTMLImageElement;
2282
+ const HTMLImageElementProtoSrcSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLImageElementProto$LWS, 'src');
2283
+ const HTMLImageElementProtoSrcsetSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLImageElementProto$LWS, 'srcset');
2177
2284
  const {
2178
2285
  prototype: HTMLInputElementProto$LWS
2179
2286
  } = HTMLInputElement;
@@ -2181,6 +2288,14 @@ const {
2181
2288
  get: HTMLInputElementProtoFormActionGetter$LWS,
2182
2289
  set: HTMLInputElementProtoFormActionSetter$LWS
2183
2290
  } = ReflectGetOwnPropertyDescriptor$LWS(HTMLInputElementProto$LWS, 'formAction');
2291
+ const {
2292
+ prototype: HTMLLinkElementProto$LWS
2293
+ } = HTMLLinkElement;
2294
+ const HTMLLinkElementProtoHrefSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLLinkElementProto$LWS, 'href');
2295
+ const {
2296
+ prototype: HTMLMediaElementProto$LWS
2297
+ } = HTMLMediaElement;
2298
+ const HTMLMediaElementProtoSrcSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLMediaElementProto$LWS, 'src');
2184
2299
  const HTMLScriptElementCtor$LWS = HTMLScriptElement;
2185
2300
  const {
2186
2301
  prototype: HTMLScriptElementProto$LWS
@@ -2189,6 +2304,24 @@ const {
2189
2304
  get: HTMLScriptElementProtoSrcGetter$LWS,
2190
2305
  set: HTMLScriptElementProtoSrcSetter$LWS
2191
2306
  } = ReflectGetOwnPropertyDescriptor$LWS(HTMLScriptElementProto$LWS, 'src');
2307
+ const {
2308
+ prototype: HTMLSourceElementProto$LWS
2309
+ } = HTMLSourceElement;
2310
+ const HTMLSourceElementProtoSrcSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLSourceElementProto$LWS, 'src');
2311
+ const HTMLSourceElementProtoSrcsetSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLSourceElementProto$LWS, 'srcset');
2312
+ const {
2313
+ prototype: HTMLTrackElementProto$LWS
2314
+ } = HTMLTrackElement;
2315
+ const HTMLTrackElementProtoSrcSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLTrackElementProto$LWS, 'src');
2316
+ const MutationObserverCtor$LWS = MutationObserver;
2317
+ const {
2318
+ prototype: MutationObserverProto$LWS
2319
+ } = MutationObserverCtor$LWS;
2320
+ const {
2321
+ disconnect: MutationObserverProtoDisconnect$LWS,
2322
+ observe: MutationObserverProtoObserve$LWS,
2323
+ takeRecords: MutationObserverProtoTakeRecords$LWS
2324
+ } = MutationObserverProto$LWS;
2192
2325
  const NAMESPACE_DEFAULT$LWS = 'default';
2193
2326
  const NAMESPACE_SVG$LWS = 'http://www.w3.org/2000/svg';
2194
2327
  const NAMESPACE_XHTML$LWS = 'http://www.w3.org/1999/xhtml';
@@ -2382,7 +2515,7 @@ const {
2382
2515
  const XhrProtoResponseTextGetter$LWS = ObjectLookupOwnGetter$LWS$1(XhrProto$LWS, 'responseText');
2383
2516
  const XhrProtoStatusGetter$LWS = ObjectLookupOwnGetter$LWS$1(XhrProto$LWS, 'status');
2384
2517
  ObjectLookupOwnSetter$LWS(XhrProto$LWS, 'withCredentials');
2385
- /*! version: 0.28.1 */
2518
+ /*! version: 0.28.3 */
2386
2519
 
2387
2520
  /*!
2388
2521
  * Copyright (C) 2019 salesforce.com, inc.
@@ -2410,7 +2543,21 @@ const DISALLOWED_ENDPOINTS_LIST$LWS = ['/aura', '/webruntime'];
2410
2543
  const DISALLOWED_BROWSING_CONTEXT_ENDPOINTS_LIST$LWS = ['/chatter'];
2411
2544
  const TRUSTED_DOMAINS_REG_EXP$LWS = /\.(force|salesforce|visualforce|documentforce|my\.site|salesforce-sites)\.com$/;
2412
2545
  const URL_SCHEMES_LIST$LWS = toSafeArray$LWS$1(['about:', 'http:', 'https:']);
2413
- const newlinesAndTabsRegExp$LWS = /[\u2028\u2029\n\r\t]/g;
2546
+ // Characters that browsers strip or ignore when resolving a URL, but that defeat
2547
+ // LWS's string-based scheme/endpoint checks if left in place. A leading invisible
2548
+ // character (e.g. U+200B before "javascript:") makes the URL parser treat the input
2549
+ // as authority-relative, leaving the scheme empty so the allowlist check is fooled;
2550
+ // an embedded one (e.g. "/se\u200btup") slips past endpoint denylist matching.
2551
+ // Stripping them before parsing closes both for every URL-bearing distortion at once.
2552
+ //
2553
+ // \p{Cc} - control characters (covers \t \n \r and the NULL byte)
2554
+ // \p{Cf} - format characters (zero-width space/joiners, soft hyphen, BOM, bidi marks
2555
+ // U+200E/U+200F/U+202A-U+202E, word joiner, etc.)
2556
+ // \u034f - combining grapheme joiner (category Mn, not Cc/Cf, but perceptually
2557
+ // invisible and ignored by the URL parser, so listed explicitly)
2558
+ // \u2028 - line separator (category Zl, not covered by Cc)
2559
+ // \u2029 - paragraph separator (category Zp, not covered by Cc)
2560
+ const strippableURLCharsRegExp$LWS = /[\0-\x1F\x7F-\x9F\xAD\u034F\u0600-\u0605\u061C\u06DD\u070F\u0890\u0891\u08E2\u180E\u200B-\u200F\u2028-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB\u{110BD}\u{110CD}\u{13430}-\u{1343F}\u{1BCA0}-\u{1BCA3}\u{1D173}-\u{1D17A}\u{E0001}\u{E0020}-\u{E007F}]/gu;
2414
2561
  const normalizerAnchor$LWS = ReflectApply$LWS$1(DocumentProtoCreateElement$LWS$1, rootDocument$LWS, ['a']);
2415
2562
  function isSameOriginURL$LWS(resourceValue$LWS) {
2416
2563
  let validParsedURL$LWS;
@@ -2434,13 +2581,18 @@ function isAttemptingToExploitURL$LWS(resourceValue$LWS) {
2434
2581
  const locationHref$LWS = rootWindow$LWS$1.location.href;
2435
2582
  return loweredResourceValue$LWS === '/' || loweredResourceValue$LWS[0] === '#' || loweredResourceValue$LWS[0] === '?' || ReflectApply$LWS$1(StringProtoStartsWith$LWS, loweredResourceValue$LWS, [`${locationHref$LWS}#`]) || ReflectApply$LWS$1(StringProtoStartsWith$LWS, loweredResourceValue$LWS, [`${locationHref$LWS}?`]);
2436
2583
  }
2437
- // Validates that a URL doesn't target disallowed endpoints
2584
+ // Validates that a URL doesn't target disallowed endpoints.
2438
2585
  // @TODO: W-7302311 Make paths and domains configurable.
2439
2586
  function isAllowedEndpointURL$LWS(parsedURL$LWS) {
2440
2587
  const loweredPathname$LWS = ReflectApply$LWS$1(StringProtoToLowerCase$LWS, parsedURL$LWS.pathname, []);
2441
2588
  // This MUST be done inside the function because the gate may not be enabled when the
2442
2589
  // module code is loaded and evaluated (as would be the case for test environments)
2443
2590
  if (isGaterEnabledFeature$LWS('changesSince.262')) {
2591
+ // Cross-origin URLs bypass the denylist — they cannot carry the user's session
2592
+ // credentials to this instance's platform-internal endpoints (W-23009170).
2593
+ if (!isSameOriginURL$LWS(parsedURL$LWS.normalizedURL)) {
2594
+ return true;
2595
+ }
2444
2596
  DISALLOWED_ENDPOINTS_LIST$LWS.push('/_nc_external', '/force', '/setup');
2445
2597
  }
2446
2598
  for (let i$LWS = 0, {
@@ -2491,9 +2643,47 @@ function sanitizeURLForElement$LWS(url$LWS) {
2491
2643
  return resolveURL$LWS(sanitizeURLString$LWS(url$LWS));
2492
2644
  }
2493
2645
  function sanitizeURLString$LWS(urlString$LWS) {
2494
- return urlString$LWS === '' ? urlString$LWS : ReflectApply$LWS$1(StringProtoReplace$LWS, urlString$LWS, [newlinesAndTabsRegExp$LWS, '']);
2646
+ return urlString$LWS === '' ? urlString$LWS : ReflectApply$LWS$1(StringProtoReplace$LWS, urlString$LWS, [strippableURLCharsRegExp$LWS, '']);
2647
+ }
2648
+ // Per the HTML spec, srcset candidates are comma-delimited. A candidate is a
2649
+ // URL optionally followed by whitespace and a width/density descriptor like
2650
+ // "480w" or "2x". URLs are unlikely to contain commas (they would have to be
2651
+ // percent-encoded to be spec-valid), so a simple comma split is sufficient
2652
+ // for LWS's validation needs — the browser will do its own spec-compliant
2653
+ // parse when it actually dispatches requests. We just need to ensure every
2654
+ // candidate URL clears isAllowedEndpointURL() before the browser sees it.
2655
+ const srcsetLeadingWhitespaceRegExp$LWS = /^[\s,]+/;
2656
+ const srcsetTrailingWhitespaceRegExp$LWS = /[\s,]+$/;
2657
+ const srcsetCandidateSplitRegExp$LWS = /\s*,\s*/;
2658
+ const srcsetWhitespaceSplitRegExp$LWS = /\s+/;
2659
+ function sanitizeSrcsetAndValidateEndpoints$LWS(rawSrcset$LWS) {
2660
+ const sanitized$LWS = sanitizeURLString$LWS(rawSrcset$LWS);
2661
+ const trimmed$LWS = ReflectApply$LWS$1(StringProtoReplace$LWS, sanitized$LWS, [srcsetLeadingWhitespaceRegExp$LWS, '']);
2662
+ const normalized$LWS = ReflectApply$LWS$1(StringProtoReplace$LWS, trimmed$LWS, [srcsetTrailingWhitespaceRegExp$LWS, '']);
2663
+ if (normalized$LWS === '') {
2664
+ return sanitized$LWS;
2665
+ }
2666
+ const candidates$LWS = ReflectApply$LWS$1(StringProtoSplit$LWS, normalized$LWS, [srcsetCandidateSplitRegExp$LWS]);
2667
+ for (let i$LWS = 0, {
2668
+ length: length$LWS
2669
+ } = candidates$LWS; i$LWS < length$LWS; i$LWS += 1) {
2670
+ const candidate$LWS = candidates$LWS[i$LWS];
2671
+ if (candidate$LWS === '') {
2672
+ continue;
2673
+ }
2674
+ const parts$LWS = ReflectApply$LWS$1(StringProtoSplit$LWS, candidate$LWS, [srcsetWhitespaceSplitRegExp$LWS]);
2675
+ const url$LWS = parts$LWS[0];
2676
+ if (!url$LWS) {
2677
+ continue;
2678
+ }
2679
+ const parsedURL$LWS = parseURL$LWS(url$LWS);
2680
+ if (!isAllowedEndpointURL$LWS(parsedURL$LWS)) {
2681
+ throw new LockerSecurityError$LWS(`Cannot request disallowed endpoint: ${toSafeTemplateStringValue$LWS(parsedURL$LWS.normalizedURL)}`);
2682
+ }
2683
+ }
2684
+ return sanitized$LWS;
2495
2685
  }
2496
- /*! version: 0.28.1 */
2686
+ /*! version: 0.28.3 */
2497
2687
 
2498
2688
  /*! @license DOMPurify 3.2.4 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.4/LICENSE */
2499
2689
 
@@ -3905,7 +4095,7 @@ try {
3905
4095
  // swallow
3906
4096
  }
3907
4097
  const trusted = createPolicy('trusted', policyOptions);
3908
- /*! version: 0.28.1 */
4098
+ /*! version: 0.28.3 */
3909
4099
 
3910
4100
  /*!
3911
4101
  * Copyright (C) 2019 salesforce.com, inc.
@@ -3973,11 +4163,17 @@ ReflectApply$LWS$1(DocumentProtoCreateElement$LWS$1, document, ['template']);
3973
4163
  const queue$LWS = toSafeSet$LWS(new SetCtor$LWS$1());
3974
4164
  // A regexp to find all non lowercase alphanumeric.
3975
4165
  const urlReplacerRegExp$LWS = /[^a-z0-9]+/gi;
3976
- function createSantizerHooksRegistry$LWS(sandboxKey$LWS) {
4166
+ function createSantizerHooksRegistry$LWS(sandboxKey$LWS, dompurifyInstance$LWS) {
3977
4167
  return {
3978
4168
  __proto__: null,
3979
- // uponSanitizeAttribute is generic, so its definition can be a reused function
3980
- uponSanitizeAttribute: uponSanitizeAttribute$LWS,
4169
+ // uponSanitizeAttribute closes over the DOMPurify instance so it can
4170
+ // ask `isValidAttribute` whether the un-suffixed base of a Lit
4171
+ // placeholder (e.g. `src$lit$` → `src`) would have been admitted by
4172
+ // DOMPurify's own allowlist. That makes the `$lit$` bypass strictly
4173
+ // narrower than DOMPurify's primary allowlist: anything the allowlist
4174
+ // would reject, the bypass also rejects — preserving the positive-list
4175
+ // invariant even for attributes the suffix would otherwise smuggle in.
4176
+ uponSanitizeAttribute: createUponSanitizeAttribute$LWS(dompurifyInstance$LWS),
3981
4177
  // uponSanitizeElement is sandbox-key-specific
3982
4178
  uponSanitizeElement(node$LWS, data$LWS, config$LWS) {
3983
4179
  var _config$CUSTOM_ELEMEN$LWS;
@@ -4022,7 +4218,7 @@ function getSanitizerForConfig$LWS(sandboxKey$LWS, configName$LWS) {
4022
4218
  const config$LWS = CONFIG$LWS[configName$LWS];
4023
4219
  configuredDOMPurifyInstance$LWS = purify();
4024
4220
  configuredDOMPurifyInstance$LWS.setConfig(config$LWS);
4025
- const hooksRegistry$LWS = createSantizerHooksRegistry$LWS(sandboxKey$LWS);
4221
+ const hooksRegistry$LWS = createSantizerHooksRegistry$LWS(sandboxKey$LWS, configuredDOMPurifyInstance$LWS);
4026
4222
  for (const hookName$LWS in hooksRegistry$LWS) {
4027
4223
  if (hookName$LWS === 'uponSanitizeElement') {
4028
4224
  configuredDOMPurifyInstance$LWS.addHook('uponSanitizeElement', hooksRegistry$LWS[hookName$LWS]);
@@ -4145,36 +4341,62 @@ function parseHref$LWS(url$LWS) {
4145
4341
  requestedURL: requestedURL$LWS
4146
4342
  };
4147
4343
  }
4148
- // Sanitize a URL representing a SVG href attribute value.
4149
- function uponSanitizeAttribute$LWS(node$LWS, data$LWS, _config$LWS) {
4150
- const {
4151
- attrValue: attrValue$LWS,
4152
- attrName: attrName$LWS
4153
- } = data$LWS;
4154
- const nodeName$LWS = ReflectApply$LWS$1(StringProtoToUpperCase$LWS, getNodeName$LWS(node$LWS), []);
4155
- if (attrValue$LWS && nodeName$LWS === 'USE' && SANITIZE_USE_ELEMENT_ATTRIBUTES_LIST$LWS.includes(attrName$LWS)) {
4156
- data$LWS.attrValue = sanitizeSvgHref$LWS(attrValue$LWS);
4157
- }
4158
- // Remove action/formaction attributes pointing to disallowed endpoints.
4159
- // Using keepAttr=false rather than blanking the value so that formaction
4160
- // removal falls back to the form's own (already validated) action attribute
4161
- // instead of overriding it with the current page URL.
4162
- if (isGaterEnabledFeature$LWS('changesSince.262') && attrValue$LWS && (attrName$LWS === 'action' || attrName$LWS === 'formaction') && (nodeName$LWS === 'FORM' || nodeName$LWS === 'BUTTON' || nodeName$LWS === 'INPUT')) {
4163
- const parsedURL$LWS = parseURL$LWS(attrValue$LWS);
4164
- if (!isAllowedEndpointURL$LWS(parsedURL$LWS)) {
4165
- data$LWS.keepAttr = false;
4344
+ // Length of Lit's attribute-name placeholder suffix ("$lit$").
4345
+ const LIT_ATTR_SUFFIX_LENGTH$LWS = 5;
4346
+ // Factory: returns a DOMPurify `uponSanitizeAttribute` hook bound to the
4347
+ // given sanitizer instance. Binding to the instance is how the `$lit$`
4348
+ // bypass below asks DOMPurify's own `isValidAttribute` whether the
4349
+ // un-suffixed base name would have been accepted by the configured
4350
+ // allowlist (ARIA_ATTR / DATA_ATTR regex or ALLOWED_ATTR \ FORBID_ATTR).
4351
+ // That check keeps the bypass strictly narrower than DOMPurify's primary
4352
+ // allowlist, so we don't smuggle through names like `onerror`, `style`,
4353
+ // `srcdoc`, or any future sink DOMPurify rejects by default.
4354
+ function createUponSanitizeAttribute$LWS(dompurifyInstance$LWS) {
4355
+ return function uponSanitizeAttribute$LWS(node$LWS, data$LWS, _config$LWS) {
4356
+ const {
4357
+ attrValue: attrValue$LWS,
4358
+ attrName: attrName$LWS
4359
+ } = data$LWS;
4360
+ const nodeName$LWS = ReflectApply$LWS$1(StringProtoToUpperCase$LWS, getNodeName$LWS(node$LWS), []);
4361
+ if (attrValue$LWS && nodeName$LWS === 'USE' && SANITIZE_USE_ELEMENT_ATTRIBUTES_LIST$LWS.includes(attrName$LWS)) {
4362
+ data$LWS.attrValue = sanitizeSvgHref$LWS(attrValue$LWS);
4363
+ }
4364
+ // Remove action/formaction attributes pointing to disallowed endpoints.
4365
+ // Using keepAttr=false rather than blanking the value so that formaction
4366
+ // removal falls back to the form's own (already validated) action attribute
4367
+ // instead of overriding it with the current page URL.
4368
+ if (isGaterEnabledFeature$LWS('changesSince.262') && attrValue$LWS && (attrName$LWS === 'action' || attrName$LWS === 'formaction') && (nodeName$LWS === 'FORM' || nodeName$LWS === 'BUTTON' || nodeName$LWS === 'INPUT')) {
4369
+ const parsedURL$LWS = parseURL$LWS(attrValue$LWS);
4370
+ if (!isAllowedEndpointURL$LWS(parsedURL$LWS)) {
4371
+ data$LWS.keepAttr = false;
4372
+ }
4166
4373
  }
4167
- }
4168
- // To support Lit, we must tell DOMPurify that attributes starting with "@", ".", or "?" are allowed.
4169
- // Ref:
4170
- // https://lit.dev/docs/components/events/
4171
- // https://lit.dev/docs/templates/expressions/#property-expressions
4172
- // https://lit.dev/docs/templates/expressions/#boolean-attribute-expressions
4173
- // istanbul ignore next: this is tested under all normal CI runs, but is not included in coverage
4174
- if (attrName$LWS && (ReflectApply$LWS$1(StringProtoStartsWith$LWS, attrName$LWS, ['@']) || ReflectApply$LWS$1(StringProtoStartsWith$LWS, attrName$LWS, ['.']) || ReflectApply$LWS$1(StringProtoStartsWith$LWS, attrName$LWS, ['?']))) {
4175
- data$LWS.forceKeepAttr = true;
4176
- }
4177
- return data$LWS;
4374
+ // To support Lit, we must tell DOMPurify that attributes starting with "@", ".", or "?" are allowed.
4375
+ // Ref:
4376
+ // https://lit.dev/docs/components/events/
4377
+ // https://lit.dev/docs/templates/expressions/#property-expressions
4378
+ // https://lit.dev/docs/templates/expressions/#boolean-attribute-expressions
4379
+ //
4380
+ // Lit also rewrites plain attribute bindings (e.g. `src="${…}"`) by appending
4381
+ // its marker suffix "$lit$" to the attribute name during HTML generation. The
4382
+ // suffixed attribute is only a placeholder that Lit removes immediately after
4383
+ // registering its AttributePart; the real value is later committed through
4384
+ // Element.prototype.setAttribute, which remains subject to the per-element
4385
+ // attribute distortion registry.
4386
+ //
4387
+ // We only force-keep the suffixed placeholder when the un-suffixed base
4388
+ // name would *also* pass DOMPurify's allowlist. Without that second
4389
+ // check, the bypass would admit any attribute ending in `$lit$` —
4390
+ // including `onerror$lit$`, `style$lit$`, `srcdoc$lit$` — and Lit would
4391
+ // then strip the suffix and commit the real value via setAttribute,
4392
+ // with no `on*` / style / srcdoc distortion to catch it. Delegating to
4393
+ // DOMPurify.isValidAttribute keeps the positive-list invariant.
4394
+ // istanbul ignore next: this is tested under all normal CI runs, but is not included in coverage
4395
+ if (attrName$LWS && (ReflectApply$LWS$1(StringProtoStartsWith$LWS, attrName$LWS, ['@']) || ReflectApply$LWS$1(StringProtoStartsWith$LWS, attrName$LWS, ['.']) || ReflectApply$LWS$1(StringProtoStartsWith$LWS, attrName$LWS, ['?']) || isGaterEnabledFeature$LWS('changesSince.264') && ReflectApply$LWS$1(StringProtoEndsWith$LWS, attrName$LWS, ['$lit$']) && dompurifyInstance$LWS.isValidAttribute(nodeName$LWS, ReflectApply$LWS$1(StringProtoSlice$LWS$1, attrName$LWS, [0, attrName$LWS.length - LIT_ATTR_SUFFIX_LENGTH$LWS]), attrValue$LWS))) {
4396
+ data$LWS.forceKeepAttr = true;
4397
+ }
4398
+ return data$LWS;
4399
+ };
4178
4400
  }
4179
4401
  function blobSanitizer$LWS(sandboxKey$LWS) {
4180
4402
  if (typeof sandboxKey$LWS !== 'string') {
@@ -4182,7 +4404,7 @@ function blobSanitizer$LWS(sandboxKey$LWS) {
4182
4404
  }
4183
4405
  return getSanitizerForConfig$LWS(sandboxKey$LWS, 'STRING_BLOB_HTML');
4184
4406
  }
4185
- /*! version: 0.28.1 */
4407
+ /*! version: 0.28.3 */
4186
4408
 
4187
4409
  /*!
4188
4410
  * Copyright (C) 2023 salesforce.com, inc.
@@ -4391,7 +4613,7 @@ function createScriptSrcURLSetter$LWS(targetElement$LWS) {
4391
4613
  ReflectApply$LWS$1(ElementProtoSetAttributeNS$LWS, targetElement$LWS, [attributeNamespaceURI$LWS, attributeName$LWS, src$LWS]);
4392
4614
  };
4393
4615
  }
4394
- /*! version: 0.28.1 */
4616
+ /*! version: 0.28.3 */
4395
4617
 
4396
4618
  /*!
4397
4619
  * Copyright (C) 2019 salesforce.com, inc.
@@ -5137,31 +5359,9 @@ function setCustomElementsRegistry$LWS(document$LWS, key$LWS) {
5137
5359
  currentRegistry$LWS = getSandboxCustomElementRegistry$LWS(document$LWS, key$LWS);
5138
5360
  }
5139
5361
  const DataTransferProtoBlockedProperties$LWS = ['mozCursor', 'mozSourceNode', 'mozUserCancelled'];
5140
-
5141
- /**
5142
- * Blocks read access to the 'nonce' attribute.
5143
- *
5144
- * The 'nonce' attribute contains a cryptographic token used by Content Security Policy
5145
- * to allow specific inline scripts/styles to execute. If malicious code can read this
5146
- * value, it can bypass CSP by injecting scripts with the stolen nonce.
5147
- *
5148
- * This function is intentionally separate from the general attribute distortion registry
5149
- * (registerAttributeDistortion/getAttributeDistortion) because that registry is designed
5150
- * for setter distortions that validate/sanitize values being set. Most blocked attributes
5151
- * (like 'srcdoc' on iframes) only need to block writes while allowing reads. The 'nonce'
5152
- * attribute is unique in that it must block both reads AND writes.
5153
- *
5154
- * By using a dedicated function, we avoid incorrectly applying setter distortions when
5155
- * reading attributes, which would cause errors for attributes like 'src' and 'href'.
5156
- */
5157
- function blockAccessToNonce$LWS(attrName$LWS) {
5158
- if (attrName$LWS === 'nonce') {
5159
- throw new LockerSecurityError$LWS("Attribute 'nonce' not accessible");
5160
- }
5161
- }
5162
5362
  const attributeDistortionFactoriesCache$LWS = toSafeMap$LWS$1(new MapCtor$LWS$1());
5163
5363
  const sandboxAttributeDistortionRegistryCache$LWS = toSafeWeakMap$LWS$1(new WeakMapCtor$LWS$1());
5164
- function finalizeAttributeDistortions$LWS(record$LWS) {
5364
+ function finalizeAttributeSetterDistortions$LWS(record$LWS) {
5165
5365
  const attributeFactories$LWS = attributeDistortionFactoriesCache$LWS.get(record$LWS);
5166
5366
  // istanbul ignore if: currently unreachable via tests
5167
5367
  if (attributeFactories$LWS === undefined) {
@@ -5221,7 +5421,7 @@ function lookupAttributeDistortion$LWS(document$LWS, key$LWS, element$LWS, attrN
5221
5421
  }
5222
5422
  return undefined;
5223
5423
  }
5224
- function getAttributeDistortion$LWS(record$LWS, element$LWS, attrName$LWS, attributeNamespace$LWS = NAMESPACE_DEFAULT$LWS) {
5424
+ function getAttributeSetterDistortion$LWS(record$LWS, element$LWS, attrName$LWS, attributeNamespace$LWS = NAMESPACE_DEFAULT$LWS) {
5225
5425
  const {
5226
5426
  document: document$LWS,
5227
5427
  key: key$LWS
@@ -5236,6 +5436,11 @@ function getAttributeDistortion$LWS(record$LWS, element$LWS, attrName$LWS, attri
5236
5436
  // to the function's realm, not the element's. Fall back to the element's
5237
5437
  // ownerDocument registry where constructors match the element's prototype
5238
5438
  // chain.
5439
+ //
5440
+ // Gated changesSince.262 because the cross-realm fallback was introduced
5441
+ // in the 262 train alongside the other cross-realm hardening; lowering
5442
+ // the gate here would re-expose 262 sandboxes to the cross-realm
5443
+ // bypass class this fallback closes.
5239
5444
  if (isGaterEnabledFeature$LWS('changesSince.262')) {
5240
5445
  const elementDocument$LWS = ReflectApply$LWS$1(NodeProtoOwnerDocumentGetter$LWS, element$LWS, []);
5241
5446
  if (elementDocument$LWS && elementDocument$LWS !== document$LWS) {
@@ -5250,7 +5455,7 @@ function getAttributeDistortion$LWS(record$LWS, element$LWS, attrName$LWS, attri
5250
5455
  function normalizeNamespace$LWS(ns$LWS) {
5251
5456
  return ns$LWS === null || ns$LWS === undefined || ns$LWS === '' ? NAMESPACE_DEFAULT$LWS : ns$LWS;
5252
5457
  }
5253
- function registerAttributeDistortion$LWS(record$LWS, ElementCtor$LWS, attributeName$LWS, attributeNamespace$LWS, distortion$LWS) {
5458
+ function registerAttributeSetterDistortion$LWS(record$LWS, ElementCtor$LWS, attributeName$LWS, attributeNamespace$LWS, distortion$LWS) {
5254
5459
  let attributeFactories$LWS = attributeDistortionFactoriesCache$LWS.get(record$LWS);
5255
5460
  if (attributeFactories$LWS === undefined) {
5256
5461
  attributeFactories$LWS = [];
@@ -5273,6 +5478,137 @@ function registerAttributeDistortion$LWS(record$LWS, ElementCtor$LWS, attributeN
5273
5478
  elementCtorMap$LWS.set(ElementCtor$LWS, distortion$LWS);
5274
5479
  };
5275
5480
  }
5481
+ const attributeGetterFactoriesCache$LWS = toSafeMap$LWS$1(new MapCtor$LWS$1());
5482
+ const sandboxAttributeGetterRegistryCache$LWS = toSafeWeakMap$LWS$1(new WeakMapCtor$LWS$1());
5483
+ function finalizeAttributeGetterDistortions$LWS(record$LWS) {
5484
+ const factories$LWS = attributeGetterFactoriesCache$LWS.get(record$LWS);
5485
+ if (factories$LWS === undefined) {
5486
+ return;
5487
+ }
5488
+ attributeGetterFactoriesCache$LWS.delete(record$LWS);
5489
+ const {
5490
+ document: document$LWS,
5491
+ key: key$LWS
5492
+ } = record$LWS;
5493
+ let sandboxRegistry$LWS = sandboxAttributeGetterRegistryCache$LWS.get(document$LWS);
5494
+ if (sandboxRegistry$LWS === undefined) {
5495
+ sandboxRegistry$LWS = {
5496
+ __proto__: null
5497
+ };
5498
+ sandboxAttributeGetterRegistryCache$LWS.set(document$LWS, sandboxRegistry$LWS);
5499
+ }
5500
+ const registry$LWS = {
5501
+ __proto__: null
5502
+ };
5503
+ sandboxRegistry$LWS[key$LWS] = registry$LWS;
5504
+ for (let i$LWS = 0, {
5505
+ length: length$LWS
5506
+ } = factories$LWS; i$LWS < length$LWS; i$LWS += 1) {
5507
+ factories$LWS[i$LWS](registry$LWS);
5508
+ }
5509
+ }
5510
+ function lookupAttributeGetterIn$LWS(document$LWS, key$LWS, element$LWS, attrName$LWS, attributeNamespace$LWS) {
5511
+ const sandboxRegistry$LWS = sandboxAttributeGetterRegistryCache$LWS.get(document$LWS);
5512
+ if (sandboxRegistry$LWS === undefined) {
5513
+ return undefined;
5514
+ }
5515
+ const registry$LWS = sandboxRegistry$LWS[key$LWS];
5516
+ if (registry$LWS === undefined) {
5517
+ return undefined;
5518
+ }
5519
+ const byNamespace$LWS = registry$LWS[ReflectApply$LWS$1(StringProtoToLowerCase$LWS, attrName$LWS, [])];
5520
+ if (byNamespace$LWS === undefined) {
5521
+ return undefined;
5522
+ }
5523
+ const ctorMap$LWS = byNamespace$LWS[attributeNamespace$LWS];
5524
+ if (ctorMap$LWS === undefined) {
5525
+ return undefined;
5526
+ }
5527
+ const it$LWS = ctorMap$LWS.entries();
5528
+ for (const {
5529
+ 0: Ctor$LWS,
5530
+ 1: getter$LWS
5531
+ } of it$LWS) {
5532
+ if (element$LWS instanceof Ctor$LWS) {
5533
+ return getter$LWS;
5534
+ }
5535
+ }
5536
+ return undefined;
5537
+ }
5538
+ function getAttributeGetterDistortion$LWS(record$LWS, element$LWS, attrName$LWS, attributeNamespace$LWS = NAMESPACE_DEFAULT$LWS) {
5539
+ // Callers pass the already-TOCTOU-coerced string; normalize here so every
5540
+ // read path looks up against a consistent (lowercased, namespace-stripped)
5541
+ // attribute-name key without each caller re-running the same transform.
5542
+ const normalizedName$LWS = normalizeNamespacedAttributeName$LWS(attrName$LWS);
5543
+ const {
5544
+ document: document$LWS,
5545
+ key: key$LWS
5546
+ } = record$LWS;
5547
+ const direct$LWS = lookupAttributeGetterIn$LWS(document$LWS, key$LWS, element$LWS, normalizedName$LWS, attributeNamespace$LWS);
5548
+ if (direct$LWS !== undefined) {
5549
+ return direct$LWS;
5550
+ }
5551
+ // Cross-realm fallback: same shape as the setter registry's, gated 262
5552
+ // for the same reason. Nonce protection on the getter side relies on
5553
+ // this fallback firing for cross-realm reads at 262 sandboxes;
5554
+ // raising this gate would re-leak nonce through cross-realm Element
5555
+ // instances on that gate.
5556
+ if (isGaterEnabledFeature$LWS('changesSince.262')) {
5557
+ const elementDocument$LWS = ReflectApply$LWS$1(NodeProtoOwnerDocumentGetter$LWS, element$LWS, []);
5558
+ if (elementDocument$LWS && elementDocument$LWS !== document$LWS) {
5559
+ return lookupAttributeGetterIn$LWS(elementDocument$LWS, key$LWS, element$LWS, normalizedName$LWS, attributeNamespace$LWS);
5560
+ }
5561
+ }
5562
+ return undefined;
5563
+ }
5564
+ function registerAttributeGetterDistortion$LWS(record$LWS, ElementCtor$LWS, attributeName$LWS, attributeNamespace$LWS, getter$LWS) {
5565
+ let factories$LWS = attributeGetterFactoriesCache$LWS.get(record$LWS);
5566
+ if (factories$LWS === undefined) {
5567
+ factories$LWS = [];
5568
+ attributeGetterFactoriesCache$LWS.set(record$LWS, factories$LWS);
5569
+ }
5570
+ const loweredAttributeName$LWS = ReflectApply$LWS$1(StringProtoToLowerCase$LWS, attributeName$LWS, []);
5571
+ factories$LWS[factories$LWS.length] = registry$LWS => {
5572
+ let byNamespace$LWS = registry$LWS[loweredAttributeName$LWS];
5573
+ if (byNamespace$LWS === undefined) {
5574
+ byNamespace$LWS = {
5575
+ __proto__: null
5576
+ };
5577
+ registry$LWS[loweredAttributeName$LWS] = byNamespace$LWS;
5578
+ }
5579
+ let ctorMap$LWS = byNamespace$LWS[attributeNamespace$LWS];
5580
+ if (ctorMap$LWS === undefined) {
5581
+ ctorMap$LWS = toSafeMap$LWS$1(new MapCtor$LWS$1());
5582
+ byNamespace$LWS[attributeNamespace$LWS] = ctorMap$LWS;
5583
+ }
5584
+ ctorMap$LWS.set(ElementCtor$LWS, getter$LWS);
5585
+ };
5586
+ }
5587
+ function initDistortionAttrValueGetter$LWS({
5588
+ globalObject: {
5589
+ Attr: Attr$LWS
5590
+ }
5591
+ }) {
5592
+ const originalAttrValueGetter$LWS = ObjectLookupOwnGetter$LWS$1(Attr$LWS.prototype, 'value');
5593
+ return function distortionAttrValueGetter$LWS(record$LWS) {
5594
+ return [originalAttrValueGetter$LWS, function value$LWS() {
5595
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
5596
+ const ownerElement$LWS = ReflectApply$LWS$1(AttrProtoOwnerElementGetter$LWS, this, []);
5597
+ if (ownerElement$LWS) {
5598
+ const attrName$LWS = ReflectApply$LWS$1(AttrProtoNameGetter$LWS, this, []);
5599
+ const attrNamespace$LWS = ReflectApply$LWS$1(AttrProtoNamespaceURIGetter$LWS, this, []);
5600
+ const normalizedNamespace$LWS = normalizeNamespace$LWS(attrNamespace$LWS);
5601
+ const override$LWS = getAttributeGetterDistortion$LWS(record$LWS, ownerElement$LWS, attrName$LWS, normalizedNamespace$LWS);
5602
+ if (override$LWS !== undefined) {
5603
+ const result$LWS = ReflectApply$LWS$1(override$LWS, ownerElement$LWS, []);
5604
+ return result$LWS === null ? '' : result$LWS;
5605
+ }
5606
+ }
5607
+ }
5608
+ return ReflectApply$LWS$1(originalAttrValueGetter$LWS, this, []);
5609
+ }];
5610
+ };
5611
+ }
5276
5612
  function initDistortionAttrValueSetter$LWS({
5277
5613
  globalObject: {
5278
5614
  Attr: Attr$LWS
@@ -5287,7 +5623,7 @@ function initDistortionAttrValueSetter$LWS({
5287
5623
  const attrName$LWS = ReflectApply$LWS$1(AttrProtoNameGetter$LWS, this, []);
5288
5624
  const attrNamespace$LWS = ReflectApply$LWS$1(AttrProtoNamespaceURIGetter$LWS, this, []);
5289
5625
  const normalizedNamespace$LWS = normalizeNamespace$LWS(attrNamespace$LWS);
5290
- const distortion$LWS = getAttributeDistortion$LWS(record$LWS, ownerElement$LWS, attrName$LWS, normalizedNamespace$LWS);
5626
+ const distortion$LWS = getAttributeSetterDistortion$LWS(record$LWS, ownerElement$LWS, attrName$LWS, normalizedNamespace$LWS);
5291
5627
  // istanbul ignore if: coverage missing, needs investigation
5292
5628
  if (distortion$LWS) {
5293
5629
  ReflectApply$LWS$1(distortion$LWS, ownerElement$LWS, [val$LWS]);
@@ -5328,6 +5664,65 @@ function initDistortionAuraUtilGlobalEval$LWS({
5328
5664
  }];
5329
5665
  };
5330
5666
  }
5667
+ function initDistortionBroadcastChannelCtor$LWS({
5668
+ globalObject: {
5669
+ BroadcastChannel: originalBroadcastChannelCtor$LWS
5670
+ }
5671
+ }) {
5672
+ // istanbul ignore if: this is a safety precaution, but currently unreachable via tests
5673
+ if (typeof originalBroadcastChannelCtor$LWS !== 'function') {
5674
+ return noop$LWS$1;
5675
+ }
5676
+ return function distortionBroadcastChannelCtor$LWS({
5677
+ key: key$LWS
5678
+ }) {
5679
+ return [originalBroadcastChannelCtor$LWS, function BroadcastChannel$LWS(...args$LWS) {
5680
+ // Namespace-prefix the channel name with the sandbox key so
5681
+ // that channels created in different sandboxes bind to
5682
+ // distinct native channel names, even when the caller
5683
+ // supplies the same visible name. Mirrors the approach used
5684
+ // for `localStorage` / `sessionStorage` / `CacheStorage` /
5685
+ // cookies.
5686
+ if (isGaterEnabledFeature$LWS('changesSince.264') && args$LWS.length) {
5687
+ args$LWS[0] = prependNamespaceMarker$LWS(toSafeStringValue$LWS(args$LWS[0]), key$LWS);
5688
+ }
5689
+ return ReflectConstruct$LWS(originalBroadcastChannelCtor$LWS, args$LWS);
5690
+ }];
5691
+ };
5692
+ }
5693
+ function initDistortionBroadcastChannelNameGetter$LWS({
5694
+ globalObject: {
5695
+ BroadcastChannel: originalBroadcastChannelCtor$LWS
5696
+ }
5697
+ }) {
5698
+ // istanbul ignore if: this is a safety precaution, but currently unreachable via tests
5699
+ if (typeof originalBroadcastChannelCtor$LWS !== 'function') {
5700
+ return noop$LWS$1;
5701
+ }
5702
+ const originalNameGetter$LWS = ObjectLookupOwnGetter$LWS$1(originalBroadcastChannelCtor$LWS.prototype, 'name');
5703
+ // istanbul ignore if: this is a safety precaution, but currently unreachable via tests
5704
+ if (typeof originalNameGetter$LWS !== 'function') {
5705
+ return noop$LWS$1;
5706
+ }
5707
+ return function distortionBroadcastChannelNameGetter$LWS({
5708
+ key: key$LWS
5709
+ }) {
5710
+ return [originalNameGetter$LWS, function name$LWS() {
5711
+ const originalName$LWS = ReflectApply$LWS$1(originalNameGetter$LWS, this, []);
5712
+ // Strip the sandbox-key namespace marker that
5713
+ // `initDistortionBroadcastChannelCtor` prepended so that the
5714
+ // visible `.name` matches the string the caller passed to
5715
+ // `new BroadcastChannel(name)` and does not leak the sandbox
5716
+ // key (via the instance or via `event.target.name` on
5717
+ // received messages).
5718
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
5719
+ return removeNamespaceMarker$LWS(originalName$LWS, key$LWS);
5720
+ }
5721
+ // istanbul ignore next: ungated return is not reachable in coverage runs
5722
+ return originalName$LWS;
5723
+ }];
5724
+ };
5725
+ }
5331
5726
  function initDistortionBroadcastChannelPostMessage$LWS({
5332
5727
  globalObject: globalObject$LWS
5333
5728
  }) {
@@ -5931,6 +6326,48 @@ function initDistortionCustomElementRegistryWhenDefined$LWS({
5931
6326
  }];
5932
6327
  };
5933
6328
  }
6329
+ const {
6330
+ isAttackerOwnedNode: isAttackerOwnedNode$1$LWS
6331
+ } = rootValidator$LWS;
6332
+ // W-22382462: gate `document.adoptNode` against the source-document
6333
+ // shape that the chain depends on.
6334
+ //
6335
+ // `adoptNode` moves a node from a *different* document into the
6336
+ // current one (transferring ownership; unlike `importNode` which
6337
+ // copies). The W-22382462 chain abuses this to lift a hostile iframe
6338
+ // (with browser-XML-parser-synthesized `srcdoc`) out of a same-origin
6339
+ // iframe contentDocument into the top-level document.
6340
+ //
6341
+ // Refusal is delegated to `rootValidator.isAttackerOwnedNode`, which
6342
+ // returns true only when the source node belongs to a document whose
6343
+ // browsing context was loaded from a non-blank URL or has a `srcdoc`
6344
+ // attribute set. Same-document adoption, adoption from detached
6345
+ // documents (`createHTMLDocument`, `DOMParser`), and adoption from
6346
+ // blank-iframed documents proceed normally.
6347
+ function initDistortionDocumentAdoptNode$LWS({
6348
+ globalObject: {
6349
+ Document: {
6350
+ prototype: {
6351
+ adoptNode: originalAdoptNode$LWS
6352
+ }
6353
+ }
6354
+ }
6355
+ }) {
6356
+ const distortionEntry$LWS = [originalAdoptNode$LWS, function adoptNode$LWS(...args$LWS) {
6357
+ if (isGaterEnabledFeature$LWS('changesSince.264') && args$LWS.length > 0) {
6358
+ const node$LWS = args$LWS[0];
6359
+ if (node$LWS !== null && node$LWS !== undefined) {
6360
+ if (isAttackerOwnedNode$1$LWS(node$LWS, this)) {
6361
+ throw new LockerSecurityError$LWS("Cannot use 'adoptNode'.");
6362
+ }
6363
+ }
6364
+ }
6365
+ return ReflectApply$LWS$1(originalAdoptNode$LWS, this, args$LWS);
6366
+ }];
6367
+ return function distortionDocumentAdoptNode$LWS() {
6368
+ return distortionEntry$LWS;
6369
+ };
6370
+ }
5934
6371
  function initDistortionDocumentCookieGetter$LWS({
5935
6372
  globalObject: {
5936
6373
  Document: Document$LWS
@@ -6196,6 +6633,48 @@ function initDistortionDocumentExecCommand$LWS({
6196
6633
  }];
6197
6634
  };
6198
6635
  }
6636
+ const {
6637
+ isAttackerOwnedNode: isAttackerOwnedNode$LWS
6638
+ } = rootValidator$LWS;
6639
+ // W-22382462 Stage 3: gate `document.importNode` against the same
6640
+ // source-document shape that `adoptNode` is gated against.
6641
+ //
6642
+ // `importNode` copies a node from a *different* document into the
6643
+ // current one. The W-22382462 chain shape is identical to the
6644
+ // adoptNode case — a hostile iframe (with browser-XML-parser-
6645
+ // synthesized `srcdoc`) being lifted out of a same-origin iframe
6646
+ // contentDocument into the top-level document.
6647
+ //
6648
+ // Refusal is delegated to `rootValidator.isAttackerOwnedNode`, which
6649
+ // returns true only when the source node belongs to a document whose
6650
+ // browsing context was loaded from a non-blank URL or has a `srcdoc`
6651
+ // attribute set. Same-document import, import from detached documents
6652
+ // (`createHTMLDocument`, `DOMParser`), and import from blank-iframed
6653
+ // documents proceed normally.
6654
+ function initDistortionDocumentImportNode$LWS({
6655
+ globalObject: {
6656
+ Document: {
6657
+ prototype: {
6658
+ importNode: originalImportNode$LWS
6659
+ }
6660
+ }
6661
+ }
6662
+ }) {
6663
+ const distortionEntry$LWS = [originalImportNode$LWS, function importNode$LWS(...args$LWS) {
6664
+ if (isGaterEnabledFeature$LWS('changesSince.264') && args$LWS.length > 0) {
6665
+ const node$LWS = args$LWS[0];
6666
+ if (node$LWS !== null && node$LWS !== undefined) {
6667
+ if (isAttackerOwnedNode$LWS(node$LWS, this)) {
6668
+ throw new LockerSecurityError$LWS("Cannot use 'importNode'.");
6669
+ }
6670
+ }
6671
+ }
6672
+ return ReflectApply$LWS$1(originalImportNode$LWS, this, args$LWS);
6673
+ }];
6674
+ return function distortionDocumentImportNode$LWS() {
6675
+ return distortionEntry$LWS;
6676
+ };
6677
+ }
6199
6678
  function initDistortionDocumentOnsecuritypolicyviolation$LWS({
6200
6679
  globalObject: {
6201
6680
  Document: {
@@ -6350,6 +6829,96 @@ function initDistortionDOMParserParseFromString$LWS({
6350
6829
  }];
6351
6830
  };
6352
6831
  }
6832
+ const ALLOW_SAME_ORIGIN_TOKEN$1$LWS = 'allow-same-origin';
6833
+ // Tokens whose addition to any DOMTokenList would relax sandbox-escape
6834
+ // boundaries. These are only meaningful on `iframe.sandbox`; on non-sandbox
6835
+ // token lists (classList, relList, etc.) they are no-ops, so a global
6836
+ // blocklist is the simplest enforcement boundary that closes the iframe
6837
+ // bypass without enumerating every host-element pairing.
6838
+ const blockedTokens$LWS = toSafeSet$LWS(new SetCtor$LWS$1([ALLOW_SAME_ORIGIN_TOKEN$1$LWS]));
6839
+ function normalizeToken$LWS(token$LWS) {
6840
+ return ReflectApply$LWS$1(StringProtoToLowerCase$LWS, toSafeStringValue$LWS(token$LWS), []);
6841
+ }
6842
+ function enforceBlockedSandboxTokenList$LWS(tokens$LWS) {
6843
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
6844
+ for (let i$LWS = 0, {
6845
+ length: length$LWS
6846
+ } = tokens$LWS; i$LWS < length$LWS; i$LWS += 1) {
6847
+ const normalized$LWS = normalizeToken$LWS(tokens$LWS[i$LWS]);
6848
+ if (blockedTokens$LWS.has(normalized$LWS)) {
6849
+ throw new LockerSecurityError$LWS(`DOMTokenList cannot accept "${normalized$LWS}" token`);
6850
+ }
6851
+ }
6852
+ }
6853
+ }
6854
+ function initDistortionDOMTokenListAdd$LWS({
6855
+ globalObject: {
6856
+ DOMTokenList: {
6857
+ prototype: {
6858
+ add: originalAdd$LWS
6859
+ }
6860
+ }
6861
+ }
6862
+ }) {
6863
+ const distortionEntry$LWS = [originalAdd$LWS, function add$LWS(...tokens$LWS) {
6864
+ enforceBlockedSandboxTokenList$LWS(tokens$LWS);
6865
+ return ReflectApply$LWS$1(DOMTokenListProtoAdd$LWS, this, tokens$LWS);
6866
+ }];
6867
+ return function distortionDOMTokenListAdd$LWS() {
6868
+ return distortionEntry$LWS;
6869
+ };
6870
+ }
6871
+ function initDistortionDOMTokenListReplace$LWS({
6872
+ globalObject: {
6873
+ DOMTokenList: {
6874
+ prototype: {
6875
+ replace: originalReplace$LWS
6876
+ }
6877
+ }
6878
+ }
6879
+ }) {
6880
+ const distortionEntry$LWS = [originalReplace$LWS, function replace$LWS(oldToken$LWS, newToken$LWS) {
6881
+ enforceBlockedSandboxTokenList$LWS([newToken$LWS]);
6882
+ return ReflectApply$LWS$1(DOMTokenListProtoReplace$LWS, this, [oldToken$LWS, newToken$LWS]);
6883
+ }];
6884
+ return function distortionDOMTokenListReplace$LWS() {
6885
+ return distortionEntry$LWS;
6886
+ };
6887
+ }
6888
+ function initDistortionDOMTokenListToggle$LWS({
6889
+ globalObject: {
6890
+ DOMTokenList: {
6891
+ prototype: {
6892
+ toggle: originalToggle$LWS
6893
+ }
6894
+ }
6895
+ }
6896
+ }) {
6897
+ const distortionEntry$LWS = [originalToggle$LWS, function toggle$LWS(token$LWS, force$LWS) {
6898
+ enforceBlockedSandboxTokenList$LWS([token$LWS]);
6899
+ return ReflectApply$LWS$1(DOMTokenListProtoToggle$LWS, this, arguments.length < 2 ? [token$LWS] : [token$LWS, force$LWS]);
6900
+ }];
6901
+ return function distortionDOMTokenListToggle$LWS() {
6902
+ return distortionEntry$LWS;
6903
+ };
6904
+ }
6905
+ const ASCII_WHITESPACE_REGEXP$LWS = /[\t\n\f\r ]+/;
6906
+ function initDistortionDOMTokenListValueSetter$LWS({
6907
+ globalObject: {
6908
+ DOMTokenList: DOMTokenList$LWS
6909
+ }
6910
+ }) {
6911
+ const originalValueSetter$LWS = ObjectLookupOwnSetter$LWS(DOMTokenList$LWS.prototype, 'value');
6912
+ const distortionEntry$LWS = [originalValueSetter$LWS, function value$LWS(newValue$LWS) {
6913
+ const normalized$LWS = toSafeStringValue$LWS(newValue$LWS);
6914
+ const tokens$LWS = ReflectApply$LWS$1(StringProtoSplit$LWS, normalized$LWS, [ASCII_WHITESPACE_REGEXP$LWS]);
6915
+ enforceBlockedSandboxTokenList$LWS(tokens$LWS);
6916
+ ReflectApply$LWS$1(DOMTokenListProtoValueSetter$LWS, this, [normalized$LWS]);
6917
+ }];
6918
+ return function distortionDOMTokenListValueSetter$LWS() {
6919
+ return distortionEntry$LWS;
6920
+ };
6921
+ }
6353
6922
  const {
6354
6923
  isSharedElement: isSharedElement$B$LWS,
6355
6924
  isAllowedSharedElementChild: isAllowedSharedElementChild$6$LWS
@@ -6463,6 +7032,9 @@ const namedNodeMapToElementCache$LWS = toSafeWeakMap$LWS$1(new WeakMapCtor$LWS$1
6463
7032
  function pairElement$LWS(attrInstance$LWS, element$LWS) {
6464
7033
  namedNodeMapToElementCache$LWS.set(attrInstance$LWS, element$LWS);
6465
7034
  }
7035
+ function getOwnerElement$LWS(nodeNameMap$LWS) {
7036
+ return namedNodeMapToElementCache$LWS.get(nodeNameMap$LWS);
7037
+ }
6466
7038
  function setNamedItemWithAttr$LWS(record$LWS, originalMethod$LWS, nodeNameMap$LWS, attr$LWS) {
6467
7039
  const element$LWS = namedNodeMapToElementCache$LWS.get(nodeNameMap$LWS);
6468
7040
  // istanbul ignore else: nothing to do if there's no element
@@ -6470,7 +7042,7 @@ function setNamedItemWithAttr$LWS(record$LWS, originalMethod$LWS, nodeNameMap$LW
6470
7042
  const attrName$LWS = ReflectApply$LWS$1(AttrProtoNameGetter$LWS, attr$LWS, []);
6471
7043
  const attrNamespace$LWS = ReflectApply$LWS$1(AttrProtoNamespaceURIGetter$LWS, attr$LWS, []);
6472
7044
  const normalizedNamespace$LWS = normalizeNamespace$LWS(attrNamespace$LWS);
6473
- const distortion$LWS = getAttributeDistortion$LWS(record$LWS, element$LWS, attrName$LWS, normalizedNamespace$LWS);
7045
+ const distortion$LWS = getAttributeSetterDistortion$LWS(record$LWS, element$LWS, attrName$LWS, normalizedNamespace$LWS);
6474
7046
  // istanbul ignore else: nothing to do if there's no distortion
6475
7047
  if (distortion$LWS) {
6476
7048
  const attrValue$LWS = ReflectApply$LWS$1(AttrProtoValueGetter$LWS, attr$LWS, []);
@@ -6538,13 +7110,21 @@ function initDistortionElementGetAttribute$LWS({
6538
7110
  }
6539
7111
  }
6540
7112
  }) {
6541
- return function distortionElementGetAttribute$LWS() {
7113
+ return function distortionElementGetAttribute$LWS(record$LWS) {
6542
7114
  return [originalGetAttribute$LWS, function getAttribute$LWS(...args$LWS) {
6543
7115
  const {
6544
7116
  length: length$LWS
6545
7117
  } = args$LWS;
6546
7118
  if (isGaterEnabledFeature$LWS('changesSince.262') && length$LWS > 0) {
6547
- blockAccessToNonce$LWS(normalizeNamespacedAttributeName$LWS(toSafeStringValue$LWS(args$LWS[0])));
7119
+ // Guard against TOCTOU attacks (e.g. shape-shifting
7120
+ // toString): force the native call to see the same
7121
+ // value our checks ran against.
7122
+ const coerced$LWS = toSafeStringValue$LWS(args$LWS[0]);
7123
+ args$LWS[0] = coerced$LWS;
7124
+ const override$LWS = getAttributeGetterDistortion$LWS(record$LWS, this, coerced$LWS);
7125
+ if (override$LWS !== undefined) {
7126
+ return ReflectApply$LWS$1(override$LWS, this, []);
7127
+ }
6548
7128
  }
6549
7129
  return ReflectApply$LWS$1(originalGetAttribute$LWS, this, args$LWS);
6550
7130
  }];
@@ -6552,6 +7132,7 @@ function initDistortionElementGetAttribute$LWS({
6552
7132
  }
6553
7133
  function initDistortionElementGetAttributeNode$LWS({
6554
7134
  globalObject: {
7135
+ document: sandboxDocument$LWS,
6555
7136
  Element: {
6556
7137
  prototype: {
6557
7138
  getAttributeNode: originalGetAttributeNode$LWS
@@ -6559,13 +7140,38 @@ function initDistortionElementGetAttributeNode$LWS({
6559
7140
  }
6560
7141
  }
6561
7142
  }) {
6562
- return function distortionElementGetAttributeNode$LWS() {
7143
+ return function distortionElementGetAttributeNode$LWS(record$LWS) {
6563
7144
  return [originalGetAttributeNode$LWS, function getAttributeNode$LWS(...args$LWS) {
6564
7145
  const {
6565
7146
  length: length$LWS
6566
7147
  } = args$LWS;
6567
7148
  if (isGaterEnabledFeature$LWS('changesSince.262') && length$LWS > 0) {
6568
- blockAccessToNonce$LWS(normalizeNamespacedAttributeName$LWS(toSafeStringValue$LWS(args$LWS[0])));
7149
+ // Guard against TOCTOU attacks: force the native call
7150
+ // to see the same value our checks ran against.
7151
+ const coerced$LWS = toSafeStringValue$LWS(args$LWS[0]);
7152
+ args$LWS[0] = coerced$LWS;
7153
+ // Consult the read-side registry. A throwing
7154
+ // registered getter (e.g. nonce) refuses the read
7155
+ // by propagating its exception. A value-substituting
7156
+ // getter (e.g. iframe.src pending URL) returns a
7157
+ // string; if the native attribute store has no Attr
7158
+ // for this name, synthesize a detached Attr carrying
7159
+ // the substituted value so sandbox code can read
7160
+ // .value as expected. If the native store already
7161
+ // has an Attr, prefer it.
7162
+ const override$LWS = getAttributeGetterDistortion$LWS(record$LWS, this, coerced$LWS);
7163
+ if (override$LWS !== undefined) {
7164
+ const overrideValue$LWS = ReflectApply$LWS$1(override$LWS, this, []);
7165
+ if (overrideValue$LWS !== null && overrideValue$LWS !== undefined) {
7166
+ const nativeAttr$LWS = ReflectApply$LWS$1(originalGetAttributeNode$LWS, this, args$LWS);
7167
+ if (nativeAttr$LWS !== null) {
7168
+ return nativeAttr$LWS;
7169
+ }
7170
+ const synth$LWS = ReflectApply$LWS$1(DocumentProtoCreateAttribute$LWS, sandboxDocument$LWS, [coerced$LWS]);
7171
+ synth$LWS.value = overrideValue$LWS;
7172
+ return synth$LWS;
7173
+ }
7174
+ }
6569
7175
  }
6570
7176
  return ReflectApply$LWS$1(originalGetAttributeNode$LWS, this, args$LWS);
6571
7177
  }];
@@ -6573,6 +7179,7 @@ function initDistortionElementGetAttributeNode$LWS({
6573
7179
  }
6574
7180
  function initDistortionElementGetAttributeNodeNS$LWS({
6575
7181
  globalObject: {
7182
+ document: sandboxDocument$LWS,
6576
7183
  Element: {
6577
7184
  prototype: {
6578
7185
  getAttributeNodeNS: originalGetAttributeNodeNS$LWS
@@ -6580,13 +7187,41 @@ function initDistortionElementGetAttributeNodeNS$LWS({
6580
7187
  }
6581
7188
  }
6582
7189
  }) {
6583
- return function distortionElementGetAttributeNodeNS$LWS() {
7190
+ return function distortionElementGetAttributeNodeNS$LWS(record$LWS) {
6584
7191
  return [originalGetAttributeNodeNS$LWS, function getAttributeNodeNS$LWS(...args$LWS) {
6585
7192
  const {
6586
7193
  length: length$LWS
6587
7194
  } = args$LWS;
6588
7195
  if (isGaterEnabledFeature$LWS('changesSince.262') && length$LWS >= 2) {
6589
- blockAccessToNonce$LWS(normalizeNamespacedAttributeName$LWS(toSafeStringValue$LWS(args$LWS[1])));
7196
+ // Guard against TOCTOU attacks: force the native call
7197
+ // to see the same values our checks ran against.
7198
+ const coercedNS$LWS = args$LWS[0] === null || args$LWS[0] === undefined ? args$LWS[0] : toSafeStringValue$LWS(args$LWS[0]);
7199
+ const coercedName$LWS = toSafeStringValue$LWS(args$LWS[1]);
7200
+ args$LWS[0] = coercedNS$LWS;
7201
+ args$LWS[1] = coercedName$LWS;
7202
+ const ns$LWS = normalizeNamespace$LWS(coercedNS$LWS);
7203
+ // Consult the read-side registry. A throwing
7204
+ // registered getter (e.g. nonce) refuses the read
7205
+ // by propagating its exception. A value-substituting
7206
+ // getter (e.g. iframe.src pending URL) returns a
7207
+ // string; if the native attribute store has no Attr
7208
+ // for this name+namespace, synthesize a detached
7209
+ // Attr carrying the substituted value so sandbox
7210
+ // code can read .value as expected. If the native
7211
+ // store already has an Attr, prefer it.
7212
+ const override$LWS = getAttributeGetterDistortion$LWS(record$LWS, this, coercedName$LWS, ns$LWS);
7213
+ if (override$LWS !== undefined) {
7214
+ const overrideValue$LWS = ReflectApply$LWS$1(override$LWS, this, []);
7215
+ if (overrideValue$LWS !== null && overrideValue$LWS !== undefined) {
7216
+ const nativeAttr$LWS = ReflectApply$LWS$1(originalGetAttributeNodeNS$LWS, this, args$LWS);
7217
+ if (nativeAttr$LWS !== null) {
7218
+ return nativeAttr$LWS;
7219
+ }
7220
+ const synth$LWS = ReflectApply$LWS$1(DocumentProtoCreateAttributeNS$LWS, sandboxDocument$LWS, [ns$LWS, coercedName$LWS]);
7221
+ synth$LWS.value = overrideValue$LWS;
7222
+ return synth$LWS;
7223
+ }
7224
+ }
6590
7225
  }
6591
7226
  return ReflectApply$LWS$1(originalGetAttributeNodeNS$LWS, this, args$LWS);
6592
7227
  }];
@@ -6601,13 +7236,23 @@ function initDistortionElementGetAttributeNS$LWS({
6601
7236
  }
6602
7237
  }
6603
7238
  }) {
6604
- return function distortionElementGetAttributeNS$LWS() {
7239
+ return function distortionElementGetAttributeNS$LWS(record$LWS) {
6605
7240
  return [originalGetAttributeNS$LWS, function getAttributeNS$LWS(...args$LWS) {
6606
7241
  const {
6607
7242
  length: length$LWS
6608
7243
  } = args$LWS;
6609
7244
  if (isGaterEnabledFeature$LWS('changesSince.262') && length$LWS >= 2) {
6610
- blockAccessToNonce$LWS(normalizeNamespacedAttributeName$LWS(toSafeStringValue$LWS(args$LWS[1])));
7245
+ // Guard against TOCTOU attacks: force the native call
7246
+ // to see the same values our checks ran against.
7247
+ const coercedNS$LWS = args$LWS[0] === null || args$LWS[0] === undefined ? args$LWS[0] : toSafeStringValue$LWS(args$LWS[0]);
7248
+ const coercedName$LWS = toSafeStringValue$LWS(args$LWS[1]);
7249
+ args$LWS[0] = coercedNS$LWS;
7250
+ args$LWS[1] = coercedName$LWS;
7251
+ const ns$LWS = normalizeNamespace$LWS(coercedNS$LWS);
7252
+ const override$LWS = getAttributeGetterDistortion$LWS(record$LWS, this, coercedName$LWS, ns$LWS);
7253
+ if (override$LWS !== undefined) {
7254
+ return ReflectApply$LWS$1(override$LWS, this, []);
7255
+ }
6611
7256
  }
6612
7257
  return ReflectApply$LWS$1(originalGetAttributeNS$LWS, this, args$LWS);
6613
7258
  }];
@@ -6713,7 +7358,7 @@ function scriptPropertySetters$LWS(incomingThis$LWS, property$LWS, valueAsTruste
6713
7358
  return false;
6714
7359
  }
6715
7360
  const {
6716
- isIframeSrcdocScriptAttack: isIframeSrcdocScriptAttack$6$LWS,
7361
+ isIframeSrcdocScriptAttack: isIframeSrcdocScriptAttack$7$LWS,
6717
7362
  isSharedElement: isSharedElement$y$LWS
6718
7363
  } = rootValidator$LWS;
6719
7364
  function initDistortionElementInnerHTMLSetter$LWS({
@@ -6768,7 +7413,7 @@ function initDistortionElementInnerHTMLSetter$LWS({
6768
7413
  // malicious markup on a later engine coercion (see toSafeStringValue() docs).
6769
7414
  value$LWS = toSafeStringValue$LWS(value$LWS);
6770
7415
  }
6771
- if (isIframeSrcdocScriptAttack$6$LWS(value$LWS)) {
7416
+ if (isIframeSrcdocScriptAttack$7$LWS(value$LWS)) {
6772
7417
  throw new LockerSecurityError$LWS(`Cannot set 'innerHTML' using an unsecure ${toSafeTemplateStringValue$LWS(value$LWS)}.`);
6773
7418
  }
6774
7419
  ReflectApply$LWS$1(originalInnerHTMLSetter$LWS, this, [value$LWS]);
@@ -6806,7 +7451,7 @@ function initDistortionElementInsertAdjacentElement$LWS({
6806
7451
  };
6807
7452
  }
6808
7453
  const {
6809
- isIframeSrcdocScriptAttack: isIframeSrcdocScriptAttack$5$LWS,
7454
+ isIframeSrcdocScriptAttack: isIframeSrcdocScriptAttack$6$LWS,
6810
7455
  isSharedElement: isSharedElement$w$LWS
6811
7456
  } = rootValidator$LWS;
6812
7457
  const allowedElementHTMLRegExp$LWS = /^\s*<(link|script|style)/i;
@@ -6838,7 +7483,7 @@ function initDistortionElementInsertAdjacentHTML$LWS({
6838
7483
  const contentType$LWS = this instanceof SVGElement ? ContentType$LWS.SVG : ContentType$LWS.HTML;
6839
7484
  args$LWS[1] = lwsInternalPolicy$LWS.createHTML(args$LWS[1], key$LWS, contentType$LWS);
6840
7485
  // If the sanitized string is still insecure, throw an exception
6841
- if (isIframeSrcdocScriptAttack$5$LWS(args$LWS[1])) {
7486
+ if (isIframeSrcdocScriptAttack$6$LWS(args$LWS[1])) {
6842
7487
  throw new LockerSecurityError$LWS(`Cannot set 'insertAdjacentHTML' using an unsecure ${toSafeTemplateStringValue$LWS(args$LWS[1])}.`);
6843
7488
  }
6844
7489
  }
@@ -6865,7 +7510,7 @@ function initDistortionElementOuterHTMLGetter$LWS({
6865
7510
  };
6866
7511
  }
6867
7512
  const {
6868
- isIframeSrcdocScriptAttack: isIframeSrcdocScriptAttack$4$LWS,
7513
+ isIframeSrcdocScriptAttack: isIframeSrcdocScriptAttack$5$LWS,
6869
7514
  isSharedElement: isSharedElement$v$LWS
6870
7515
  } = rootValidator$LWS;
6871
7516
  function initDistortionElementOuterHTMLSetter$LWS({
@@ -6891,7 +7536,7 @@ function initDistortionElementOuterHTMLSetter$LWS({
6891
7536
  const html$LWS = lwsInternalPolicy$LWS.createHTML(value$LWS, key$LWS, ContentType$LWS.HTML);
6892
7537
  // Ensure that the created html snippet is secure (no mXSS)
6893
7538
  if (isGaterEnabledFeature$LWS('changesSince.260')) {
6894
- if (isIframeSrcdocScriptAttack$4$LWS(html$LWS)) {
7539
+ if (isIframeSrcdocScriptAttack$5$LWS(html$LWS)) {
6895
7540
  throw new LockerSecurityError$LWS(`Cannot set 'outerHTML' using an unsecure ${toSafeTemplateStringValue$LWS(value$LWS)}.`);
6896
7541
  }
6897
7542
  }
@@ -6961,6 +7606,89 @@ function initDistortionElementRemove$LWS({
6961
7606
  return distortionEntry$LWS;
6962
7607
  };
6963
7608
  }
7609
+
7610
+ // Intentionally narrow: only 'sandbox' needs protection today. If more iframe
7611
+ // attributes require removal-blocking in the future, generalize to a Set.
7612
+ const SANDBOX_ATTR$4$LWS = 'sandbox';
7613
+ function initDistortionElementRemoveAttribute$LWS({
7614
+ globalObject: {
7615
+ Element: {
7616
+ prototype: {
7617
+ removeAttribute: originalRemoveAttribute$LWS
7618
+ }
7619
+ },
7620
+ HTMLIFrameElement: HTMLIFrameElement$LWS
7621
+ }
7622
+ }) {
7623
+ const distortionEntry$LWS = [originalRemoveAttribute$LWS, function removeAttribute$LWS(...args$LWS) {
7624
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
7625
+ if (args$LWS.length > 0) {
7626
+ const attrName$LWS = ReflectApply$LWS$1(StringProtoToLowerCase$LWS, toSafeStringValue$LWS(args$LWS[0]), []);
7627
+ if (attrName$LWS === SANDBOX_ATTR$4$LWS && this instanceof HTMLIFrameElement$LWS) {
7628
+ throw new LockerSecurityError$LWS("Cannot remove 'sandbox' attribute from HTMLIFrameElement.");
7629
+ }
7630
+ }
7631
+ }
7632
+ return ReflectApply$LWS$1(ElementProtoRemoveAttribute$LWS, this, args$LWS);
7633
+ }];
7634
+ return function distortionElementRemoveAttribute$LWS() {
7635
+ return distortionEntry$LWS;
7636
+ };
7637
+ }
7638
+ const SANDBOX_ATTR$3$LWS = 'sandbox';
7639
+ function initDistortionElementRemoveAttributeNode$LWS({
7640
+ globalObject: {
7641
+ Attr: Attr$LWS,
7642
+ Element: {
7643
+ prototype: {
7644
+ removeAttributeNode: originalRemoveAttributeNode$LWS
7645
+ }
7646
+ },
7647
+ HTMLIFrameElement: HTMLIFrameElement$LWS
7648
+ }
7649
+ }) {
7650
+ const distortionEntry$LWS = [originalRemoveAttributeNode$LWS, function removeAttributeNode$LWS(...args$LWS) {
7651
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
7652
+ const attr$LWS = args$LWS.length ? args$LWS[0] : undefined;
7653
+ if (attr$LWS instanceof Attr$LWS) {
7654
+ const attrName$LWS = ReflectApply$LWS$1(StringProtoToLowerCase$LWS, ReflectApply$LWS$1(AttrProtoNameGetter$LWS, attr$LWS, []), []);
7655
+ if (attrName$LWS === SANDBOX_ATTR$3$LWS && this instanceof HTMLIFrameElement$LWS) {
7656
+ throw new LockerSecurityError$LWS("Cannot remove 'sandbox' attribute from HTMLIFrameElement.");
7657
+ }
7658
+ }
7659
+ }
7660
+ return ReflectApply$LWS$1(ElementProtoRemoveAttributeNode$LWS, this, args$LWS);
7661
+ }];
7662
+ return function distortionElementRemoveAttributeNode$LWS() {
7663
+ return distortionEntry$LWS;
7664
+ };
7665
+ }
7666
+ const SANDBOX_ATTR$2$LWS = 'sandbox';
7667
+ function initDistortionElementRemoveAttributeNS$LWS({
7668
+ globalObject: {
7669
+ Element: {
7670
+ prototype: {
7671
+ removeAttributeNS: originalRemoveAttributeNS$LWS
7672
+ }
7673
+ },
7674
+ HTMLIFrameElement: HTMLIFrameElement$LWS
7675
+ }
7676
+ }) {
7677
+ const distortionEntry$LWS = [originalRemoveAttributeNS$LWS, function removeAttributeNS$LWS(...args$LWS) {
7678
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
7679
+ if (args$LWS.length > 1) {
7680
+ const attrName$LWS = ReflectApply$LWS$1(StringProtoToLowerCase$LWS, toSafeStringValue$LWS(args$LWS[1]), []);
7681
+ if (attrName$LWS === SANDBOX_ATTR$2$LWS && this instanceof HTMLIFrameElement$LWS) {
7682
+ throw new LockerSecurityError$LWS("Cannot remove 'sandbox' attribute from HTMLIFrameElement.");
7683
+ }
7684
+ }
7685
+ }
7686
+ return ReflectApply$LWS$1(ElementProtoRemoveAttributeNS$LWS, this, args$LWS);
7687
+ }];
7688
+ return function distortionElementRemoveAttributeNS$LWS() {
7689
+ return distortionEntry$LWS;
7690
+ };
7691
+ }
6964
7692
  const {
6965
7693
  isSharedElement: isSharedElement$s$LWS
6966
7694
  } = rootValidator$LWS;
@@ -7021,7 +7749,7 @@ function initDistortionElementSetAttribute$LWS({
7021
7749
  if (args$LWS.length > 1) {
7022
7750
  const attrName$LWS = normalizeNamespacedAttributeName$LWS(toSafeStringValue$LWS(args$LWS[0]));
7023
7751
  const attrValue$LWS = toSafeStringValue$LWS(args$LWS[1]);
7024
- const distortion$LWS = getAttributeDistortion$LWS(record$LWS, this, attrName$LWS);
7752
+ const distortion$LWS = getAttributeSetterDistortion$LWS(record$LWS, this, attrName$LWS);
7025
7753
  if (distortion$LWS) {
7026
7754
  ReflectApply$LWS$1(distortion$LWS, this, [attrValue$LWS]);
7027
7755
  return;
@@ -7064,7 +7792,7 @@ function initDistortionElementSetAttributeNode$LWS({
7064
7792
  const attrName$LWS = normalizeNamespacedAttributeName$LWS(ReflectApply$LWS$1(AttrProtoNameGetter$LWS, attr$LWS, []));
7065
7793
  const attrNamespace$LWS = ReflectApply$LWS$1(AttrProtoNamespaceURIGetter$LWS, attr$LWS, []);
7066
7794
  const normalizedNamespace$LWS = normalizeNamespace$LWS(attrNamespace$LWS);
7067
- const distortion$LWS = getAttributeDistortion$LWS(record$LWS, this, attrName$LWS, normalizedNamespace$LWS);
7795
+ const distortion$LWS = getAttributeSetterDistortion$LWS(record$LWS, this, attrName$LWS, normalizedNamespace$LWS);
7068
7796
  if (distortion$LWS) {
7069
7797
  const oldAttr$LWS = ReflectApply$LWS$1(ElementProtoGetAttributeNode$LWS, this, [attrName$LWS]);
7070
7798
  if (oldAttr$LWS) {
@@ -7122,7 +7850,7 @@ function initDistortionElementSetAttributeNodeNS$LWS({
7122
7850
  const attrName$LWS = normalizeNamespacedAttributeName$LWS(ReflectApply$LWS$1(AttrProtoNameGetter$LWS, attr$LWS, []));
7123
7851
  const attrNamespace$LWS = ReflectApply$LWS$1(AttrProtoNamespaceURIGetter$LWS, attr$LWS, []);
7124
7852
  const normalizedNamespace$LWS = normalizeNamespace$LWS(attrNamespace$LWS);
7125
- const distortion$LWS = getAttributeDistortion$LWS(record$LWS, this, attrName$LWS, normalizedNamespace$LWS);
7853
+ const distortion$LWS = getAttributeSetterDistortion$LWS(record$LWS, this, attrName$LWS, normalizedNamespace$LWS);
7126
7854
  if (distortion$LWS) {
7127
7855
  const oldAttr$LWS = ReflectApply$LWS$1(ElementProtoGetAttributeNodeNS$LWS, this, [attrNamespace$LWS, attrName$LWS]);
7128
7856
  if (oldAttr$LWS) {
@@ -7178,7 +7906,7 @@ function initDistortionElementSetAttributeNS$LWS({
7178
7906
  const attrName$LWS = normalizeNamespacedAttributeName$LWS(toSafeStringValue$LWS(args$LWS[1]));
7179
7907
  const attrValue$LWS = toSafeStringValue$LWS(args$LWS[2]);
7180
7908
  const normalizedNamespace$LWS = normalizeNamespace$LWS(attrNamespace$LWS);
7181
- const distortion$LWS = getAttributeDistortion$LWS(record$LWS, this, attrName$LWS, normalizedNamespace$LWS);
7909
+ const distortion$LWS = getAttributeSetterDistortion$LWS(record$LWS, this, attrName$LWS, normalizedNamespace$LWS);
7182
7910
  // istanbul ignore else: needs default platform behavior test
7183
7911
  if (distortion$LWS) {
7184
7912
  ReflectApply$LWS$1(distortion$LWS, this, [attrValue$LWS]);
@@ -7204,7 +7932,7 @@ function initDistortionElementSetAttributeNS$LWS({
7204
7932
  };
7205
7933
  }
7206
7934
  const {
7207
- isIframeSrcdocScriptAttack: isIframeSrcdocScriptAttack$3$LWS,
7935
+ isIframeSrcdocScriptAttack: isIframeSrcdocScriptAttack$4$LWS,
7208
7936
  isSharedElement: isSharedElement$q$LWS
7209
7937
  } = rootValidator$LWS;
7210
7938
  function initDistortionElementSetHTML$LWS({
@@ -7249,7 +7977,7 @@ function initDistortionElementSetHTML$LWS({
7249
7977
  // This will be in addition to the sanitization we have.
7250
7978
  const contentType$LWS = isSVGElement$LWS ? ContentType$LWS.SVG : ContentType$LWS.HTML;
7251
7979
  args$LWS[0] = lwsInternalPolicy$LWS.createHTML(normalizedValue$LWS, key$LWS, contentType$LWS);
7252
- if (isIframeSrcdocScriptAttack$3$LWS(args$LWS[0])) {
7980
+ if (isIframeSrcdocScriptAttack$4$LWS(args$LWS[0])) {
7253
7981
  throw new LockerSecurityError$LWS(`Cannot 'setHTML' using an unsecure ${toSafeTemplateStringValue$LWS(args$LWS[0])}.`);
7254
7982
  }
7255
7983
  }
@@ -7258,7 +7986,7 @@ function initDistortionElementSetHTML$LWS({
7258
7986
  };
7259
7987
  }
7260
7988
  const {
7261
- isIframeSrcdocScriptAttack: isIframeSrcdocScriptAttack$2$LWS,
7989
+ isIframeSrcdocScriptAttack: isIframeSrcdocScriptAttack$3$LWS,
7262
7990
  isSharedElement: isSharedElement$p$LWS
7263
7991
  } = rootValidator$LWS;
7264
7992
  function initDistortionElementSetHTMLUnsafe$LWS({
@@ -7319,7 +8047,7 @@ function initDistortionElementSetHTMLUnsafe$LWS({
7319
8047
  const contentType$LWS = isSVGElement$LWS ? ContentType$LWS.SVG : ContentType$LWS.HTML;
7320
8048
  normalizedValue$LWS = lwsInternalPolicy$LWS.createHTML(normalizedValue$LWS, key$LWS, contentType$LWS);
7321
8049
  }
7322
- if (isIframeSrcdocScriptAttack$2$LWS(normalizedValue$LWS)) {
8050
+ if (isIframeSrcdocScriptAttack$3$LWS(normalizedValue$LWS)) {
7323
8051
  throw new LockerSecurityError$LWS(`Cannot 'setHTMLUnsafe' using an unsecure ${toSafeTemplateStringValue$LWS(normalizedValue$LWS)}.`);
7324
8052
  }
7325
8053
  ReflectApply$LWS$1(originalSetHTMLUnsafe$LWS, this, [normalizedValue$LWS]);
@@ -7362,7 +8090,7 @@ function initDistortionElementToggleAttribute$LWS({
7362
8090
  // istanbul ignore else: needs default platform behavior test
7363
8091
  if (length$LWS > 0) {
7364
8092
  const attrName$LWS = toSafeStringValue$LWS(args$LWS[0]);
7365
- const distortion$LWS = getAttributeDistortion$LWS(record$LWS, this, attrName$LWS);
8093
+ const distortion$LWS = getAttributeSetterDistortion$LWS(record$LWS, this, attrName$LWS);
7366
8094
  // istanbul ignore else: needs default platform behavior test
7367
8095
  if (distortion$LWS) {
7368
8096
  const distortionArgs$LWS = length$LWS > 1 ? [args$LWS[1]] : [];
@@ -7496,6 +8224,184 @@ function initDistortionEventTargetAddEventListener$LWS({
7496
8224
  return [originalAddEventListener$LWS, addEventListener$LWS];
7497
8225
  };
7498
8226
  }
8227
+
8228
+ // @W-18977628 — Reserved event types that sandboxed code must never dispatch.
8229
+ // These are internal Aura framework events whose listeners run outside the
8230
+ // sandbox and pass privileged unsandboxed references to the caller.
8231
+ const BLOCKED_DISPATCH_EVENT_TYPES$LWS = toSafeSet$LWS(new SetCtor$LWS$1(['aurainteropfindowner']));
8232
+ function initDistortionEventTargetDispatchEvent$LWS({
8233
+ globalObject: {
8234
+ EventTarget: {
8235
+ prototype: {
8236
+ dispatchEvent: originalDispatchEvent$LWS
8237
+ }
8238
+ }
8239
+ }
8240
+ }) {
8241
+ return function distortionEventTargetDispatchEvent$LWS() {
8242
+ function dispatchEvent$LWS(...args$LWS) {
8243
+ const {
8244
+ length: length$LWS
8245
+ } = args$LWS;
8246
+ // Ensure that we fallback to the default platform behavior which
8247
+ // should fail if less than 1 argument is provided.
8248
+ // istanbul ignore else: needs default platform behavior test
8249
+ if (length$LWS > 0 && isGaterEnabledFeature$LWS('changesSince.264')) {
8250
+ const eventType$LWS = toSafeStringValue$LWS(ReflectApply$LWS$1(EventProtoTypeGetter$LWS, args$LWS[0], []));
8251
+ if (BLOCKED_DISPATCH_EVENT_TYPES$LWS.has(eventType$LWS)) {
8252
+ throw new LockerSecurityError$LWS(`Cannot dispatch '${eventType$LWS}' event.`);
8253
+ }
8254
+ }
8255
+ return ReflectApply$LWS$1(originalDispatchEvent$LWS, this, args$LWS);
8256
+ }
8257
+ return [originalDispatchEvent$LWS, dispatchEvent$LWS];
8258
+ };
8259
+ }
8260
+
8261
+ // W-22602807: shared helper for distorting an iframe contentWindow realm's
8262
+ // function-invocation primitives (Function.prototype.call/apply/bind,
8263
+ // Reflect.apply/construct).
8264
+ //
8265
+ // The cross-realm leak: sandbox code obtains a same-origin iframe's invocation
8266
+ // primitive and uses it to invoke a constructor/evaluator. The callee can
8267
+ // arrive as a RAW callable whose realm's `document` is undistorted, so
8268
+ // `document.cookie` in a compiled body resolves to the native getter and leaks
8269
+ // the top-level cookie.
8270
+ //
8271
+ // Containment tracks the OUTERMOST primitive actually invoked through the
8272
+ // membrane (composition depth is irrelevant: in `apply.call(F, ...)` only the
8273
+ // outer `.call` is invoked). So every invocation primitive reachable on the
8274
+ // iframe realm must be distorted. Each re-resolves the callee (the function
8275
+ // being invoked) to its distorted counterpart in the ROOT record's map when
8276
+ // one exists, then delegates to the native primitive — so a raw native
8277
+ // Function/eval reached cross-realm becomes the sandbox-distorted version,
8278
+ // while ordinary usage is an untouched passthrough.
8279
+ // Returns the host iframe element if `globalObject
8280
+ // ` is a same-origin iframe
8281
+ // contentWindow realm (the only realm we distort), else undefined. Gated on
8282
+ // changesSince.264: when the gate is off, no entry is installed and the
8283
+ // primitive keeps its native behavior. One check here covers all five
8284
+ // invocation-primitive distortions.
8285
+ function getDistortableFrameElement$LWS(globalObject$LWS) {
8286
+ if (!isGaterEnabledFeature$LWS('changesSince.264')) {
8287
+ return undefined;
8288
+ }
8289
+ let frameElement$LWS;
8290
+ try {
8291
+ frameElement$LWS = ReflectApply$LWS$1(WindowFrameElementGetter$LWS, globalObject$LWS, []);
8292
+ } catch (_unused2$LWS) {
8293
+ // Cross-origin / non-window realm: not our target.
8294
+ return undefined;
8295
+ }
8296
+ return frameElement$LWS || undefined;
8297
+ }
8298
+ // Re-resolve `callee` to its distorted counterpart from the root distortion
8299
+ // map, if one exists; otherwise return it unchanged.
8300
+ //
8301
+ // This reads the assembled `root.distortions` map at invocation time — the same
8302
+ // map the near-membrane's distortionCallback consults. That is deliberate: a
8303
+ // foreign invocation primitive can deliver a callee (e.g. the sandbox `Function`
8304
+ // ctor) that has crossed the membrane as a RAW reference, bypassing the
8305
+ // distortion the membrane would normally apply on a direct call. Looking the
8306
+ // callee up in the map re-attaches that distortion. We rely on the map's
8307
+ // invariant that a callable key maps to a callable replacement; the
8308
+ // `distorted !== callee` check skips identity mappings (e.g. `document`,
8309
+ // `location`, the global object, which map to themselves), and the invocation
8310
+ // primitives require a callable target regardless, so a non-callable could
8311
+ // never be reached here without throwing at the call site.
8312
+ function substituteDistortedCallee$LWS(root$LWS, callee$LWS) {
8313
+ const distorted$LWS = root$LWS.distortions.get(callee$LWS);
8314
+ if (distorted$LWS !== undefined && distorted$LWS !== callee$LWS) {
8315
+ return distorted$LWS;
8316
+ }
8317
+ return callee$LWS;
8318
+ }
8319
+
8320
+ // W-22602807: distort an iframe contentWindow realm's Function.prototype.apply.
8321
+ // See cross-realm-invocation.ts for the threat model.
8322
+ function initDistortionFunctionApply$LWS({
8323
+ globalObject: {
8324
+ Function: {
8325
+ prototype: {
8326
+ apply: originalApply$LWS
8327
+ }
8328
+ }
8329
+ }
8330
+ }) {
8331
+ return function distortionFunctionApply$LWS({
8332
+ globalObject: globalObject$LWS,
8333
+ root: root$LWS
8334
+ }) {
8335
+ if (!getDistortableFrameElement$LWS(globalObject$LWS)) {
8336
+ return undefined;
8337
+ }
8338
+ return [originalApply$LWS,
8339
+ // `this` is the callee; (thisArg, argsArray) its binding and args.
8340
+ // `apply` accepts a null/undefined argsArray, which ReflectApply
8341
+ // rejects, so normalize to [].
8342
+ function apply$LWS(thisArg$LWS, argsArray$LWS) {
8343
+ return ReflectApply$LWS$1(substituteDistortedCallee$LWS(root$LWS, this), thisArg$LWS, argsArray$LWS == null ? [] : argsArray$LWS);
8344
+ }];
8345
+ };
8346
+ }
8347
+
8348
+ // W-22602807: distort an iframe contentWindow realm's Function.prototype.bind.
8349
+ // See cross-realm-invocation.ts for the threat model.
8350
+ //
8351
+ // bind defers invocation: it returns a bound function invoked later. We
8352
+ // substitute the callee for its distorted counterpart FIRST, then bind that,
8353
+ // so the returned bound function wraps the sandbox-distorted callee.
8354
+ function initDistortionFunctionBind$LWS({
8355
+ globalObject: {
8356
+ Function: {
8357
+ prototype: {
8358
+ bind: originalBind$LWS
8359
+ }
8360
+ }
8361
+ }
8362
+ }) {
8363
+ return function distortionFunctionBind$LWS({
8364
+ globalObject: globalObject$LWS,
8365
+ root: root$LWS
8366
+ }) {
8367
+ if (!getDistortableFrameElement$LWS(globalObject$LWS)) {
8368
+ return undefined;
8369
+ }
8370
+ return [originalBind$LWS,
8371
+ // `this` is the callee; (thisArg, ...boundArgs) the binding and
8372
+ // partially-applied args. Bind the substituted callee with the
8373
+ // sandbox-realm bind so the result is a sandbox-realm bound function.
8374
+ function bind$LWS(thisArg$LWS, ...boundArgs$LWS) {
8375
+ return ReflectApply$LWS$1(FunctionProtoBind$LWS, substituteDistortedCallee$LWS(root$LWS, this), [thisArg$LWS, ...boundArgs$LWS]);
8376
+ }];
8377
+ };
8378
+ }
8379
+
8380
+ // W-22602807: distort an iframe contentWindow realm's Function.prototype.call.
8381
+ // See cross-realm-invocation.ts for the threat model.
8382
+ function initDistortionFunctionCall$LWS({
8383
+ globalObject: {
8384
+ Function: {
8385
+ prototype: {
8386
+ call: originalCall$LWS
8387
+ }
8388
+ }
8389
+ }
8390
+ }) {
8391
+ return function distortionFunctionCall$LWS({
8392
+ globalObject: globalObject$LWS,
8393
+ root: root$LWS
8394
+ }) {
8395
+ if (!getDistortableFrameElement$LWS(globalObject$LWS)) {
8396
+ return undefined;
8397
+ }
8398
+ return [originalCall$LWS,
8399
+ // `this` is the callee; (thisArg, ...args) its binding and arguments.
8400
+ function call$LWS(thisArg$LWS, ...args$LWS) {
8401
+ return ReflectApply$LWS$1(substituteDistortedCallee$LWS(root$LWS, this), thisArg$LWS, args$LWS);
8402
+ }];
8403
+ };
8404
+ }
7499
8405
  function initDistortionFunction$LWS({
7500
8406
  UNCOMPILED_CONTEXT: UNCOMPILED_CONTEXT$LWS,
7501
8407
  globalObject: {
@@ -7596,11 +8502,35 @@ function initDistortionHistoryReplaceState$LWS({
7596
8502
  };
7597
8503
  }
7598
8504
 
7599
- // Anchor elements allow blob: URLs in addition to standard schemes for download links
7600
- const ANCHOR_URL_SCHEMES_LIST$LWS = toSafeArray$LWS$1(['about:', 'blob:', 'http:', 'https:']);
7601
- function isValidAnchorURLScheme$LWS(url$LWS) {
8505
+ // Only schemes that can trigger arbitrary JavaScript execution when an anchor is
8506
+ // navigated are blocked. Everything else (mailto:, tel:, sms:, http:, https:,
8507
+ // blob:, about:, relative urls) is permitted: those navigate or hand off to an
8508
+ // external app and cannot execute script.
8509
+ // eslint-disable-next-line no-script-url
8510
+ const ANCHOR_BLOCKED_URL_SCHEMES_LIST$LWS = toSafeArray$LWS$1(['data:', 'javascript:', 'vbscript:']);
8511
+ const ANCHOR_BLOCKED_SCHEME_ERROR_MESSAGE$LWS = 'HTMLAnchorElement href does not support data:, javascript: or vbscript: schemes.';
8512
+ // The scheme is read back through the browser's own URL parser via the
8513
+ // normalizer anchor, so case/whitespace/zero-width evasion variants resolve to
8514
+ // the same normalized protocol the browser would execute. A payload that does
8515
+ // not normalize to a blocked scheme is also not executed as one by the browser.
8516
+ function normalizedSchemeIsBlocked$LWS() {
8517
+ return ANCHOR_BLOCKED_URL_SCHEMES_LIST$LWS.includes(ReflectApply$LWS$1(HTMLAnchorElementProtoProtocolGetter$LWS, normalizerAnchor$LWS, []));
8518
+ }
8519
+ // Guards the `href` setter / `href` attribute: the whole URL is assigned to the
8520
+ // normalizer, then its resolved protocol is checked.
8521
+ function isBlockedAnchorHref$LWS(url$LWS) {
7602
8522
  ReflectApply$LWS$1(HTMLAnchorElementProtoHrefSetter$LWS, normalizerAnchor$LWS, [url$LWS]);
7603
- return ANCHOR_URL_SCHEMES_LIST$LWS.includes(ReflectApply$LWS$1(HTMLAnchorElementProtoProtocolGetter$LWS, normalizerAnchor$LWS, []));
8523
+ return normalizedSchemeIsBlocked$LWS();
8524
+ }
8525
+ // Guards the `protocol` setter: `a.protocol = value` resolves against the
8526
+ // anchor's current href, so the same current href is replayed onto the
8527
+ // normalizer before applying the new scheme. This mirrors exactly what the
8528
+ // native setter would produce, on a throwaway anchor.
8529
+ function isBlockedAnchorProtocolChange$LWS(anchor$LWS, value$LWS) {
8530
+ const currentHref$LWS = ReflectApply$LWS$1(HTMLAnchorElementProtoHrefGetter$LWS, anchor$LWS, []);
8531
+ ReflectApply$LWS$1(HTMLAnchorElementProtoHrefSetter$LWS, normalizerAnchor$LWS, [currentHref$LWS]);
8532
+ ReflectApply$LWS$1(HTMLAnchorElementProtoProtocolSetter$LWS, normalizerAnchor$LWS, [value$LWS]);
8533
+ return normalizedSchemeIsBlocked$LWS();
7604
8534
  }
7605
8535
  function initDistortionHTMLAnchorElementHrefSetter$LWS({
7606
8536
  globalObject: {
@@ -7610,20 +8540,45 @@ function initDistortionHTMLAnchorElementHrefSetter$LWS({
7610
8540
  const originalHrefSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLAnchorElement$LWS.prototype, 'href');
7611
8541
  function href$LWS(value$LWS) {
7612
8542
  const urlString$LWS = sanitizeURLForElement$LWS(value$LWS);
7613
- if (isGaterEnabledFeature$LWS('changesSince.262') && !isValidAnchorURLScheme$LWS(urlString$LWS)) {
7614
- throw new LockerSecurityError$LWS('HTMLAnchorElement.href supports http://, https://, blob: schemes, relative urls and about:blank.');
8543
+ if (isGaterEnabledFeature$LWS('htmlAnchorElementHrefValidation')) {
8544
+ if (isBlockedAnchorHref$LWS(urlString$LWS)) {
8545
+ throw new LockerSecurityError$LWS(ANCHOR_BLOCKED_SCHEME_ERROR_MESSAGE$LWS);
8546
+ }
8547
+ const parsedURL$LWS = parseURL$LWS(urlString$LWS);
8548
+ if (!isAllowedEndpointURL$LWS(parsedURL$LWS)) {
8549
+ throw new LockerSecurityError$LWS(`Cannot request disallowed endpoint: ${toSafeTemplateStringValue$LWS(parsedURL$LWS.normalizedURL)}`);
8550
+ }
7615
8551
  }
7616
8552
  ReflectApply$LWS$1(HTMLAnchorElementProtoHrefSetter$LWS, this, [urlString$LWS]);
7617
8553
  }
7618
8554
  const distortionEntry$LWS = [originalHrefSetter$LWS, href$LWS];
7619
8555
  return function distortionHTMLAnchorElementHrefSetter$LWS(record$LWS) {
7620
- if (isGaterEnabledFeature$LWS('changesSince.262')) {
7621
- registerAttributeDistortion$LWS(record$LWS, HTMLAnchorElement$LWS, 'href', NAMESPACE_DEFAULT$LWS, href$LWS);
8556
+ if (isGaterEnabledFeature$LWS('htmlAnchorElementHrefValidation')) {
8557
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLAnchorElement$LWS, 'href', NAMESPACE_DEFAULT$LWS, href$LWS);
7622
8558
  }
7623
8559
  // This will fall back to the original href setter if the gate is not enabled
7624
8560
  return distortionEntry$LWS;
7625
8561
  };
7626
8562
  }
8563
+ function initDistortionHTMLAnchorElementProtocolSetter$LWS({
8564
+ globalObject: {
8565
+ HTMLAnchorElement: HTMLAnchorElement$LWS
8566
+ }
8567
+ }) {
8568
+ const originalProtocolSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLAnchorElement$LWS.prototype, 'protocol');
8569
+ function protocol$LWS(value$LWS) {
8570
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
8571
+ if (isBlockedAnchorProtocolChange$LWS(this, value$LWS)) {
8572
+ throw new LockerSecurityError$LWS(ANCHOR_BLOCKED_SCHEME_ERROR_MESSAGE$LWS);
8573
+ }
8574
+ }
8575
+ ReflectApply$LWS$1(originalProtocolSetter$LWS, this, [value$LWS]);
8576
+ }
8577
+ const distortionEntry$LWS = [originalProtocolSetter$LWS, protocol$LWS];
8578
+ return function distortionHTMLAnchorElementProtocolSetter$LWS() {
8579
+ return distortionEntry$LWS;
8580
+ };
8581
+ }
7627
8582
  function initDistortionHTMLBaseElementHrefSetter$LWS({
7628
8583
  globalObject: {
7629
8584
  HTMLBaseElement: HTMLBaseElement$LWS
@@ -7686,7 +8641,7 @@ function initDistortionHTMLButtonElementFormActionSetter$LWS({
7686
8641
  }
7687
8642
  ReflectApply$LWS$1(HTMLButtonElementProtoFormActionSetter$LWS, this, [urlString$LWS]);
7688
8643
  }
7689
- registerAttributeDistortion$LWS(record$LWS, HTMLButtonElement$LWS, 'formaction', NAMESPACE_DEFAULT$LWS, formAction$LWS);
8644
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLButtonElement$LWS, 'formaction', NAMESPACE_DEFAULT$LWS, formAction$LWS);
7690
8645
  return [originalFormActionSetter$LWS, formAction$LWS];
7691
8646
  }
7692
8647
  // istanbul ignore next: ungated return is not reachable in coverage runs
@@ -7865,7 +8820,7 @@ function initDistortionHTMLFormElementActionSetter$LWS({
7865
8820
  }
7866
8821
  ReflectApply$LWS$1(HTMLFormElementProtoActionSetter$LWS, this, [urlString$LWS]);
7867
8822
  }
7868
- registerAttributeDistortion$LWS(record$LWS, HTMLFormElement$LWS, 'action', NAMESPACE_DEFAULT$LWS, action$LWS);
8823
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLFormElement$LWS, 'action', NAMESPACE_DEFAULT$LWS, action$LWS);
7869
8824
  return [originalActionSetter$LWS, action$LWS];
7870
8825
  }
7871
8826
  // istanbul ignore next: ungated return is not reachable in coverage runs
@@ -7942,13 +8897,145 @@ function initDistortionHTMLIFrameElementSandboxGetter$LWS({
7942
8897
  }];
7943
8898
  };
7944
8899
  }
8900
+
8901
+ // Provenance: the design for this pipeline (per-iframe pending-URL
8902
+ const pendingURLs$LWS = toSafeWeakMap$LWS$1(new WeakMapCtor$LWS$1());
8903
+ const inflightControllers$LWS = toSafeWeakMap$LWS$1(new WeakMapCtor$LWS$1());
8904
+ // W-22382462: iframes whose pre-flight detected an attack pattern in the
8905
+ // fetched response body. The setter checks this set at entry and throws
8906
+ // synchronously on any subsequent write attempt, so the violation is
8907
+ // observable from sandboxed code on the *next* sync touchpoint after
8908
+ // the async pre-flight resolved hostile.
8909
+ const poisonedIframes$LWS = toSafeWeakSet$LWS$1(new WeakSetCtor$LWS$1());
8910
+ // W-22382462: cross-iframe URL rejection cache. When a pre-flight
8911
+ // detects hostile, the URL's pathname is added here. Any subsequent
8912
+ // iframe.src assignment to a URL with the same pathname (regardless of
8913
+ // the iframe instance, query string, or fragment) throws synchronously
8914
+ // without re-fetching. Rationale: in this threat model attacker-
8915
+ // controllable content surfaces are deployable static resources whose
8916
+ // pathname maps 1:1 to their body. Re-fetching the same hostile body
8917
+ // for every fresh iframe is wasted work and provides an attacker a
8918
+ // re-attempt window if a transient network failure lets the second
8919
+ // fetch succeed where the first failed; pathname-keyed rejection
8920
+ // closes both.
8921
+ const rejectedPathnames$LWS = toSafeSet$LWS(new SetCtor$LWS$1());
8922
+ const detachedPending$LWS = toSafeMap$LWS$1(new MapCtor$LWS$1());
8923
+ function getPendingURL$LWS(iframe$LWS) {
8924
+ return pendingURLs$LWS.get(iframe$LWS);
8925
+ }
8926
+ function setPendingURL$LWS(iframe$LWS, url$LWS) {
8927
+ pendingURLs$LWS.set(iframe$LWS, url$LWS);
8928
+ }
8929
+ function clearPendingURL$LWS(iframe$LWS) {
8930
+ pendingURLs$LWS.delete(iframe$LWS);
8931
+ }
8932
+ function abortInflightPreflight$LWS(iframe$LWS) {
8933
+ const controller$LWS = inflightControllers$LWS.get(iframe$LWS);
8934
+ if (controller$LWS !== undefined) {
8935
+ ReflectApply$LWS$1(AbortControllerProtoAbort$LWS, controller$LWS, []);
8936
+ inflightControllers$LWS.delete(iframe$LWS);
8937
+ }
8938
+ }
8939
+ function trackInflightPreflight$LWS(iframe$LWS, controller$LWS) {
8940
+ inflightControllers$LWS.set(iframe$LWS, controller$LWS);
8941
+ }
8942
+ function clearInflightPreflight$LWS(iframe$LWS) {
8943
+ inflightControllers$LWS.delete(iframe$LWS);
8944
+ }
8945
+ function poisonIframe$LWS(iframe$LWS) {
8946
+ poisonedIframes$LWS.add(iframe$LWS);
8947
+ }
8948
+ function isPoisonedIframe$LWS(iframe$LWS) {
8949
+ return poisonedIframes$LWS.has(iframe$LWS);
8950
+ }
8951
+ function rejectPathname$LWS(pathname$LWS) {
8952
+ rejectedPathnames$LWS.add(pathname$LWS);
8953
+ }
8954
+ function isRejectedPathname$LWS(pathname$LWS) {
8955
+ return rejectedPathnames$LWS.has(pathname$LWS);
8956
+ }
8957
+ function setDetachedPending$LWS(iframe$LWS, entry$LWS) {
8958
+ detachedPending$LWS.set(iframe$LWS, entry$LWS);
8959
+ }
8960
+ function clearDetachedPending$LWS(iframe$LWS) {
8961
+ detachedPending$LWS.delete(iframe$LWS);
8962
+ }
8963
+ function forEachDetachedPending$LWS(callback$LWS) {
8964
+ detachedPending$LWS.forEach((entry$LWS, iframe$LWS) => {
8965
+ callback$LWS(iframe$LWS, entry$LWS);
8966
+ });
8967
+ }
8968
+
8969
+ // Provenance: the W-22382462 same-origin async pre-flight pipeline added
8970
+ const {
8971
+ isIframeSrcdocAttack: isIframeSrcdocAttack$LWS,
8972
+ isXMLEntityAttack: isXMLEntityAttack$LWS,
8973
+ isXMLNamespacedScriptAttack: isXMLNamespacedScriptAttack$LWS
8974
+ } = rootValidator$LWS;
7945
8975
  const ABOUT_BLANK_TOKEN$LWS = 'about:blank';
7946
8976
  const ALLOW_SAME_ORIGIN_TOKEN$LWS = 'allow-same-origin';
7947
8977
  const ALLOW_SCRIPTS_TOKEN$LWS = 'allow-scripts';
7948
8978
  const sameOriginSandboxedByLWS$LWS = toSafeWeakSet$LWS$1(new WeakSetCtor$LWS$1());
7949
- function enforceSandboxAllowScriptsForSameOriginIframeRealm$LWS(iframe$LWS) {
8979
+ // W-22382462: connection observer for detached iframes with pending
8980
+ // same-origin URLs. The browser only fetches an iframe's src when the
8981
+ // iframe is connected to a document; setting src on a detached iframe
8982
+ // records the attribute but does not initiate any network activity
8983
+ // until attachment. The original pre-flight implementation skipped
8984
+ // detached iframes and wrote the native attribute eagerly, which left
8985
+ // a hole: a hostile URL set on a detached iframe and then attached
8986
+ // via `appendChild` would auto-fetch and parse before any LWS check
8987
+ // ran. The fix: defer both the native write AND the pre-flight until
8988
+ // the iframe is observed to enter a connected subtree, then run the
8989
+ // existing pre-flight pipeline at that moment. The native attribute
8990
+ // stays unwritten through the inspection window, so the browser never
8991
+ // auto-fetches a hostile body without our approval.
8992
+ //
8993
+ // One observer at module scope handles all detached-pending iframes
8994
+ // regardless of which sandbox set their src. The observer's callback
8995
+ // iterates the small detached-pending Map (typically empty or 1-2
8996
+ // entries) and dispatches the deferred pre-flight for any iframe
8997
+ // that is now connected. Lazy registration: the observer is wired up
8998
+ // the first time any setter parks a URL on a detached iframe, so
8999
+ // sandboxes that never use detached iframes pay no observer cost.
9000
+ let connectionObserverRegistered$LWS = false;
9001
+ function ensureConnectionObserverRegistered$LWS() {
9002
+ if (connectionObserverRegistered$LWS) {
9003
+ return;
9004
+ }
9005
+ connectionObserverRegistered$LWS = true;
9006
+ const observer$LWS = new MutationObserverCtor$LWS(() => {
9007
+ forEachDetachedPending$LWS((iframe$LWS, entry$LWS) => {
9008
+ if (ReflectApply$LWS$1(NodeProtoIsConnectedGetter$LWS, iframe$LWS, [])) {
9009
+ clearDetachedPending$LWS(iframe$LWS);
9010
+ entry$LWS.runDeferredPreflight();
9011
+ }
9012
+ });
9013
+ });
9014
+ ReflectApply$LWS$1(MutationObserverProtoObserve$LWS, observer$LWS, [rootDocument$LWS, {
9015
+ __proto__: null,
9016
+ childList: true,
9017
+ subtree: true
9018
+ }]);
9019
+ }
9020
+ function enforceSandboxAllowScriptsForSameOriginIframeRealm$LWS(iframe$LWS, srcValueOverride$LWS) {
7950
9021
  const sandboxTokenList$LWS = ReflectApply$LWS$1(HTMLIFrameElementProtoSandboxGetter$LWS, iframe$LWS, []);
7951
- const srcValue$LWS = ReflectApply$LWS$1(HTMLIFrameElementProtoSrcGetter$LWS, iframe$LWS, []);
9022
+ // Source of truth for the iframe's effective src, in priority order:
9023
+ // 1. Explicit override from the caller (the pre-flight setter's
9024
+ // synchronous call passes the queued URL).
9025
+ // 2. Pending URL from the registry-backed bookkeeping (any other
9026
+ // caller, e.g. iframe.sandbox = '...', running while a
9027
+ // pre-flight is in flight: the queued URL is the URL the
9028
+ // iframe will end up at when the pre-flight commits, so the
9029
+ // sandbox classification must reflect that, not the native
9030
+ // attribute store which is still empty).
9031
+ // 3. The native src getter (fall-through; no pending state).
9032
+ let srcValue$LWS;
9033
+ if (srcValueOverride$LWS !== undefined) {
9034
+ srcValue$LWS = srcValueOverride$LWS;
9035
+ } else {
9036
+ const pending$LWS = getPendingURL$LWS(iframe$LWS);
9037
+ srcValue$LWS = pending$LWS !== undefined ? pending$LWS : ReflectApply$LWS$1(HTMLIFrameElementProtoSrcGetter$LWS, iframe$LWS, []);
9038
+ }
7952
9039
  // Before adding "allow-scripts", check that "allow-same-origin" isn't present. If it is,
7953
9040
  // throw an exception because LWS cannot allow an iframe created by component code to
7954
9041
  // have sandbox="allow-same-origin allow-scripts", because that would enable access to
@@ -7969,7 +9056,7 @@ function enforceSandboxAllowScriptsForSameOriginIframeRealm$LWS(iframe$LWS) {
7969
9056
  if (!isSameOriginURL$LWS(srcValue$LWS)) {
7970
9057
  return;
7971
9058
  }
7972
- } catch (_unused2$LWS) {
9059
+ } catch (_unused3$LWS) {
7973
9060
  /* empty */
7974
9061
  }
7975
9062
  if (!ReflectApply$LWS$1(DOMTokenListProtoContains$LWS, sandboxTokenList$LWS, [ALLOW_SCRIPTS_TOKEN$LWS])) {
@@ -7994,12 +9081,23 @@ function enforceSandboxAllowScriptsForSameOriginIframeRealm$LWS(iframe$LWS) {
7994
9081
  }
7995
9082
  function initDistortionHTMLIFrameElementSrcSetter$LWS({
7996
9083
  globalObject: {
7997
- HTMLIFrameElement: HTMLIFrameElement$LWS
9084
+ HTMLIFrameElement: HTMLIFrameElement$LWS,
9085
+ fetch: originalFetch$LWS
7998
9086
  }
7999
9087
  }) {
8000
9088
  const originalSrcSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLIFrameElement$LWS.prototype, 'src');
8001
9089
  return function distortionHTMLIFrameElementSrcSetter$LWS(record$LWS) {
8002
9090
  function src$LWS(value$LWS) {
9091
+ // If a prior async pre-flight on this iframe detected an
9092
+ // attack-pattern in the fetched body, the iframe is permanently
9093
+ // poisoned. Any subsequent synchronous write attempt throws,
9094
+ // so the security violation surfaces at the call site of the
9095
+ // FOLLOWING `iframe.src = ...` (or setAttribute('src',...) etc.)
9096
+ // even though we cannot synchronously propagate the original
9097
+ // hostile-detection back to its triggering setter call.
9098
+ if (isGaterEnabledFeature$LWS('changesSince.264') && isPoisonedIframe$LWS(this)) {
9099
+ throw new LockerSecurityError$LWS('HTMLIFrameElement is poisoned: a prior src assignment fetched a body containing an attack pattern. The iframe cannot be reused.');
9100
+ }
8003
9101
  const normalizedSrcValue$LWS = toSafeStringValue$LWS(value$LWS);
8004
9102
  // This must be done on the raw value before sanitization, because sanitization can
8005
9103
  // remove the exploit pattern.
@@ -8024,12 +9122,208 @@ function initDistortionHTMLIFrameElementSrcSetter$LWS({
8024
9122
  throw new LockerSecurityError$LWS(`Cannot request disallowed endpoint: ${toSafeTemplateStringValue$LWS(normalizedURL$LWS)}`);
8025
9123
  }
8026
9124
  }
9125
+ // Same-origin URLs go through an async pre-flight that fetches
9126
+ // the resource and runs its body through the rootValidator
9127
+ // attack-pattern checks. Any future-added pattern (XML entity
9128
+ // smuggling, iframe-srcdoc script injection, namespaced-script
9129
+ // payloads, etc.) is automatically picked up by virtue of going
9130
+ // through the same validators every other HTML-handling
9131
+ // distortion does. Same-origin guarantees the pre-flight body
9132
+ // is byte-identical to what the iframe load would receive
9133
+ // (attacker-controllable content surfaces in this threat model
9134
+ // are deployable static resources, which serve identical bytes
9135
+ // for every request). Cross-origin URLs proceed through the
9136
+ // existing pipeline unchanged because the JS layer cannot
9137
+ // inspect cross-origin response bodies and SOP already contains
9138
+ // the cross-origin contentDocument.
9139
+ //
9140
+ // Detached iframes can't pre-flight at set-time (the browser
9141
+ // hasn't queued any load), but they MUST NOT have their native
9142
+ // src written eagerly either: the moment such an iframe is
9143
+ // attached, the browser would auto-fetch and parse the body
9144
+ // before any LWS check could run. Instead, the URL is parked
9145
+ // in a detached-pending map and a connection observer dispatches
9146
+ // the deferred pre-flight when the iframe enters a connected
9147
+ // subtree. Native attribute stays unwritten until pre-flight
9148
+ // resolves. Pending URL is recorded normally so read paths
9149
+ // (iframe.src, getAttribute('src'), attributes['src'].value)
9150
+ // surface what sandbox code wrote.
9151
+ if (isGaterEnabledFeature$LWS('changesSince.264') && urlString$LWS !== '' && urlString$LWS !== ABOUT_BLANK_TOKEN$LWS && isSameOriginURL$LWS(urlString$LWS)) {
9152
+ // Cross-iframe rejection cache: if any prior pre-flight
9153
+ // (on this iframe or any other) detected an attack
9154
+ // pattern at this URL's pathname, refuse the assignment
9155
+ // synchronously without re-fetching. Runs regardless of
9156
+ // attached/detached state — a known-hostile pathname
9157
+ // is rejected at the call site.
9158
+ const parsedURL$LWS = parseURL$LWS(urlString$LWS);
9159
+ if (isRejectedPathname$LWS(parsedURL$LWS.pathname)) {
9160
+ throw new LockerSecurityError$LWS(`Cannot set src to "${toSafeTemplateStringValue$LWS(urlString$LWS)}": pathname previously rejected as containing an attack pattern.`);
9161
+ }
9162
+ if (ReflectApply$LWS$1(NodeProtoIsConnectedGetter$LWS, this, [])) {
9163
+ preflightSameOriginAndCommit$LWS(this, urlString$LWS, parsedURL$LWS.pathname, record$LWS);
9164
+ // Sandbox enforcement is deferred to onSafe so that
9165
+ // navigation occurs with the iframe's original sandbox
9166
+ // state. Adding `allow-scripts` synchronously here would
9167
+ // mark the iframe `sandbox="allow-scripts"` (without
9168
+ // `allow-same-origin`) at navigation time, which per
9169
+ // spec yields an opaque cross-origin browsing context
9170
+ // even for same-origin URLs. onSafe runs the helper
9171
+ // after the native src setter, matching the
9172
+ // legacy-path order where the iframe navigates with the
9173
+ // pre-existing sandbox state and `allow-scripts` is
9174
+ // added afterward.
9175
+ return;
9176
+ }
9177
+ // Detached: write native and run sandbox enforcement
9178
+ // synchronously (preserves the legacy-path
9179
+ // `setAttributeNodeNS` Attr-replacement semantics and
9180
+ // the synchronous read of `iframe.sandbox` after
9181
+ // `iframe.src = ...`). Then park the URL and register
9182
+ // the connection observer. When the iframe is later
9183
+ // attached, the observer reads the native src, clears
9184
+ // it (which aborts the browser's queued navigation per
9185
+ // HTML spec — changing src during a navigate aborts
9186
+ // the in-flight load), and runs the deferred
9187
+ // pre-flight. On safe, native src is written back and
9188
+ // the browser navigates. On hostile, native stays
9189
+ // cleared and the iframe is poisoned.
9190
+ //
9191
+ // The native write is safe while detached: the browser
9192
+ // does not navigate iframes that are not connected to
9193
+ // a document, so no fetch occurs until attachment, at
9194
+ // which point our observer interposes before the
9195
+ // browser's load task runs.
9196
+ const iframe$LWS = this;
9197
+ ReflectApply$LWS$1(HTMLIFrameElementProtoSrcSetter$LWS, iframe$LWS, [urlString$LWS]);
9198
+ if (isGaterEnabledFeature$LWS(ENABLE_SANDBOXED_SAMEORIGIN_IFRAME_GATE$LWS) && isNotAllowedToOverrideGaterEnabledFeature$LWS(record$LWS.key, ENABLE_SANDBOXED_SAMEORIGIN_IFRAME_GATE$LWS)) {
9199
+ enforceSandboxAllowScriptsForSameOriginIframeRealm$LWS(iframe$LWS);
9200
+ }
9201
+ setDetachedPending$LWS(iframe$LWS, {
9202
+ url: urlString$LWS,
9203
+ pathname: parsedURL$LWS.pathname,
9204
+ runDeferredPreflight: () => {
9205
+ // Clear the native src to abort the navigation
9206
+ // the browser queued at attach time. HTML spec:
9207
+ // when src changes during a navigation, the
9208
+ // prior navigation is aborted. After clearing,
9209
+ // the pre-flight runs against the saved URL
9210
+ // and writes native back on safe.
9211
+ ReflectApply$LWS$1(ElementProtoRemoveAttribute$LWS, iframe$LWS, ['src']);
9212
+ preflightSameOriginAndCommit$LWS(iframe$LWS, urlString$LWS, parsedURL$LWS.pathname, record$LWS);
9213
+ }
9214
+ });
9215
+ ensureConnectionObserverRegistered$LWS();
9216
+ return;
9217
+ }
9218
+ // Any non-pre-flight write (cross-origin, empty, about:blank,
9219
+ // or pre-264) supersedes a pending pre-flight: abort it,
9220
+ // clear pending state, then write native. This guarantees
9221
+ // the helper below sees the actual post-write native src
9222
+ // (not a stale pending URL from the prior assignment).
9223
+ abortInflightPreflight$LWS(this);
9224
+ clearPendingURL$LWS(this);
9225
+ clearDetachedPending$LWS(this);
9226
+ clearInflightPreflight$LWS(this);
8027
9227
  ReflectApply$LWS$1(HTMLIFrameElementProtoSrcSetter$LWS, this, [urlString$LWS]);
8028
9228
  if (isGaterEnabledFeature$LWS(ENABLE_SANDBOXED_SAMEORIGIN_IFRAME_GATE$LWS) && isNotAllowedToOverrideGaterEnabledFeature$LWS(record$LWS.key, ENABLE_SANDBOXED_SAMEORIGIN_IFRAME_GATE$LWS)) {
8029
9229
  enforceSandboxAllowScriptsForSameOriginIframeRealm$LWS(this);
8030
9230
  }
8031
9231
  }
8032
- registerAttributeDistortion$LWS(record$LWS, HTMLIFrameElement$LWS, 'src', NAMESPACE_DEFAULT$LWS, src$LWS);
9232
+ // Same-origin async pre-flight pipeline. The setter remains
9233
+ // synchronous from sandboxed code's perspective: it returns after
9234
+ // recording the pending URL and kicking off the fetch. The native
9235
+ // attribute is NOT written until the pre-flight approves the body,
9236
+ // so the browser does not start navigating until then. Read-after-
9237
+ // write surfaces (iframe.src, getAttribute('src'), attributes['src']
9238
+ // via the iframe.src getter distortion + read-side getter registry)
9239
+ // see the pending URL during the inspection window.
9240
+ function preflightSameOriginAndCommit$LWS(iframe$LWS, urlString$LWS, pathname$LWS, sandboxRecord$LWS) {
9241
+ // Re-assignment cancels any prior pre-flight in flight on this
9242
+ // iframe and replaces it with the new URL.
9243
+ abortInflightPreflight$LWS(iframe$LWS);
9244
+ setPendingURL$LWS(iframe$LWS, urlString$LWS);
9245
+ const controller$LWS = new AbortControllerCtor$LWS();
9246
+ const signal$LWS = ReflectApply$LWS$1(AbortControllerProtoSignalGetter$LWS, controller$LWS, []);
9247
+ trackInflightPreflight$LWS(iframe$LWS, controller$LWS);
9248
+ const isSupersededOrAborted$LWS = () => signal$LWS.aborted;
9249
+ const onSafe$LWS = () => {
9250
+ if (isSupersededOrAborted$LWS()) {
9251
+ return;
9252
+ }
9253
+ clearPendingURL$LWS(iframe$LWS);
9254
+ clearInflightPreflight$LWS(iframe$LWS);
9255
+ ReflectApply$LWS$1(HTMLIFrameElementProtoSrcSetter$LWS, iframe$LWS, [urlString$LWS]);
9256
+ if (isGaterEnabledFeature$LWS(ENABLE_SANDBOXED_SAMEORIGIN_IFRAME_GATE$LWS) && isNotAllowedToOverrideGaterEnabledFeature$LWS(sandboxRecord$LWS.key, ENABLE_SANDBOXED_SAMEORIGIN_IFRAME_GATE$LWS)) {
9257
+ enforceSandboxAllowScriptsForSameOriginIframeRealm$LWS(iframe$LWS);
9258
+ }
9259
+ };
9260
+ const onHostile$LWS = () => {
9261
+ if (isSupersededOrAborted$LWS()) {
9262
+ return;
9263
+ }
9264
+ clearPendingURL$LWS(iframe$LWS);
9265
+ clearInflightPreflight$LWS(iframe$LWS);
9266
+ // Native src is intentionally left unwritten; the iframe
9267
+ // never navigates to the hostile URL. Mark the iframe as
9268
+ // poisoned so the next synchronous write attempt throws.
9269
+ // The original iframe.src = url callsite returned long
9270
+ // ago; we cannot synchronously propagate the throw back
9271
+ // to it, but any subsequent setter / setAttribute / etc.
9272
+ // on this iframe will throw at the new call site.
9273
+ poisonIframe$LWS(iframe$LWS);
9274
+ // Add the pathname to the cross-iframe rejection cache
9275
+ // so any future iframe whose src lands at the same
9276
+ // pathname throws synchronously at setter entry without
9277
+ // re-fetching. Pathname-keyed (not full URL) so query-
9278
+ // string rotation can't evade the cache.
9279
+ rejectPathname$LWS(pathname$LWS);
9280
+ };
9281
+ const onAborted$LWS = () => {
9282
+ clearInflightPreflight$LWS(iframe$LWS);
9283
+ };
9284
+ ReflectApply$LWS$1(originalFetch$LWS, undefined, [urlString$LWS, {
9285
+ __proto__: null,
9286
+ credentials: 'same-origin',
9287
+ signal: signal$LWS
9288
+ }]).then(response$LWS => response$LWS.text()).then(body$LWS => {
9289
+ if (isSupersededOrAborted$LWS()) {
9290
+ onAborted$LWS();
9291
+ return;
9292
+ }
9293
+ // Validator union scoped to the patterns that
9294
+ // matter for iframe.src bodies: iframe+srcdoc
9295
+ // substring combo (a child iframe with srcdoc
9296
+ // smuggled into the parent page), XML DOCTYPE
9297
+ // entity expansion (XXE), and XML-namespaced
9298
+ // script elements that execute in XML contexts
9299
+ // but are inert in HTML. The broader
9300
+ // `isIframeSrcdocScriptAttack` (which also flags
9301
+ // any obfuscated <script>) is intentionally NOT
9302
+ // used here — existing test fixtures and component
9303
+ // code rely on iframe.src loading <script>-bearing
9304
+ // same-origin pages (legacy contract; the iframe
9305
+ // sandbox is the layer that contains script
9306
+ // execution). Tightening this would break that
9307
+ // contract.
9308
+ if (isIframeSrcdocAttack$LWS(body$LWS) || isXMLEntityAttack$LWS(body$LWS) || isXMLNamespacedScriptAttack$LWS(body$LWS)) {
9309
+ onHostile$LWS();
9310
+ } else {
9311
+ onSafe$LWS();
9312
+ }
9313
+ }).catch(() => {
9314
+ if (isSupersededOrAborted$LWS()) {
9315
+ onAborted$LWS();
9316
+ return;
9317
+ }
9318
+ // Network error or non-2xx. The browser's own iframe
9319
+ // load would also fail; commit the URL so the iframe's
9320
+ // onerror fires through the normal navigation-failure
9321
+ // path. (We deliberately don't poison on transport
9322
+ // errors — only on attack-pattern detection.)
9323
+ onSafe$LWS();
9324
+ });
9325
+ }
9326
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLIFrameElement$LWS, 'src', NAMESPACE_DEFAULT$LWS, src$LWS);
8033
9327
  return [originalSrcSetter$LWS, src$LWS];
8034
9328
  };
8035
9329
  }
@@ -8046,10 +9340,88 @@ function initDistortionHTMLIFrameElementSandboxSetter$LWS({
8046
9340
  enforceSandboxAllowScriptsForSameOriginIframeRealm$LWS(this);
8047
9341
  }
8048
9342
  }
8049
- registerAttributeDistortion$LWS(record$LWS, HTMLIFrameElement$LWS, 'sandbox', NAMESPACE_DEFAULT$LWS, sandbox$LWS);
9343
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLIFrameElement$LWS, 'sandbox', NAMESPACE_DEFAULT$LWS, sandbox$LWS);
8050
9344
  return [originalSandboxSetter$LWS, sandbox$LWS];
8051
9345
  };
8052
9346
  }
9347
+
9348
+ // HTMLIFrameElement.src getter distortion. Returns the pending URL recorded
9349
+ // by the src setter's pre-flight pipeline (see src-setter.ts) when one
9350
+ // exists, otherwise falls through to the native getter.
9351
+ //
9352
+ // The same getter is registered into the read-side attribute getter
9353
+ // registry under (HTMLIFrameElement, 'src'), so el.getAttribute('src'),
9354
+ // el.getAttributeNS, el.attributes['src'].value, etc. all surface the
9355
+ // pending URL through the registry consultation in those distortions.
9356
+ function initDistortionHTMLIFrameElementSrcGetter$LWS({
9357
+ globalObject: {
9358
+ HTMLIFrameElement: HTMLIFrameElement$LWS
9359
+ }
9360
+ }) {
9361
+ const originalSrcGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLIFrameElement$LWS.prototype, 'src');
9362
+ return function distortionHTMLIFrameElementSrcGetter$LWS(record$LWS) {
9363
+ function src$LWS() {
9364
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
9365
+ const pending$LWS = getPendingURL$LWS(this);
9366
+ if (pending$LWS !== undefined) {
9367
+ return pending$LWS;
9368
+ }
9369
+ }
9370
+ return ReflectApply$LWS$1(originalSrcGetter$LWS, this, []);
9371
+ }
9372
+ // The pending-URL pipeline that backs this getter is W-22382462
9373
+ // gate-264 work; only register into the read-side attribute
9374
+ // getter registry when the gate is on, otherwise pre-264
9375
+ // sandboxes pay the registry-consultation cost on every
9376
+ // iframe.src read with no behavior change to show for it.
9377
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
9378
+ registerAttributeGetterDistortion$LWS(record$LWS, HTMLIFrameElement$LWS, 'src', NAMESPACE_DEFAULT$LWS, src$LWS);
9379
+ }
9380
+ return [originalSrcGetter$LWS, src$LWS];
9381
+ };
9382
+ }
9383
+ function initDistortionHTMLImageElementSrcSetter$LWS({
9384
+ globalObject: {
9385
+ HTMLImageElement: HTMLImageElement$LWS
9386
+ }
9387
+ }) {
9388
+ const originalSrcSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLImageElement$LWS.prototype, 'src');
9389
+ return function distortionHTMLImageElementSrcSetter$LWS(record$LWS) {
9390
+ function src$LWS(value$LWS) {
9391
+ const normalized$LWS = toSafeStringValue$LWS(value$LWS);
9392
+ const urlString$LWS = normalized$LWS === '' ? '' : sanitizeURLForElement$LWS(normalized$LWS);
9393
+ if (urlString$LWS !== '' && isGaterEnabledFeature$LWS('changesSince.264')) {
9394
+ const parsedURL$LWS = parseURL$LWS(urlString$LWS);
9395
+ if (!isAllowedEndpointURL$LWS(parsedURL$LWS)) {
9396
+ throw new LockerSecurityError$LWS(`Cannot request disallowed endpoint: ${toSafeTemplateStringValue$LWS(parsedURL$LWS.normalizedURL)}`);
9397
+ }
9398
+ }
9399
+ ReflectApply$LWS$1(HTMLImageElementProtoSrcSetter$LWS, this, [urlString$LWS]);
9400
+ }
9401
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
9402
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLImageElement$LWS, 'src', NAMESPACE_DEFAULT$LWS, src$LWS);
9403
+ }
9404
+ return [originalSrcSetter$LWS, src$LWS];
9405
+ };
9406
+ }
9407
+ function initDistortionHTMLImageElementSrcsetSetter$LWS({
9408
+ globalObject: {
9409
+ HTMLImageElement: HTMLImageElement$LWS
9410
+ }
9411
+ }) {
9412
+ const originalSrcsetSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLImageElement$LWS.prototype, 'srcset');
9413
+ return function distortionHTMLImageElementSrcsetSetter$LWS(record$LWS) {
9414
+ function srcset$LWS(value$LWS) {
9415
+ const normalized$LWS = toSafeStringValue$LWS(value$LWS);
9416
+ const finalValue$LWS = normalized$LWS !== '' && isGaterEnabledFeature$LWS('changesSince.264') ? sanitizeSrcsetAndValidateEndpoints$LWS(normalized$LWS) : normalized$LWS;
9417
+ ReflectApply$LWS$1(HTMLImageElementProtoSrcsetSetter$LWS, this, [finalValue$LWS]);
9418
+ }
9419
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
9420
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLImageElement$LWS, 'srcset', NAMESPACE_DEFAULT$LWS, srcset$LWS);
9421
+ }
9422
+ return [originalSrcsetSetter$LWS, srcset$LWS];
9423
+ };
9424
+ }
8053
9425
  function initDistortionHTMLInputElementFormActionSetter$LWS({
8054
9426
  globalObject: {
8055
9427
  HTMLInputElement: HTMLInputElement$LWS
@@ -8073,13 +9445,42 @@ function initDistortionHTMLInputElementFormActionSetter$LWS({
8073
9445
  }
8074
9446
  ReflectApply$LWS$1(HTMLInputElementProtoFormActionSetter$LWS, this, [urlString$LWS]);
8075
9447
  }
8076
- registerAttributeDistortion$LWS(record$LWS, HTMLInputElement$LWS, 'formaction', NAMESPACE_DEFAULT$LWS, formAction$LWS);
9448
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLInputElement$LWS, 'formaction', NAMESPACE_DEFAULT$LWS, formAction$LWS);
8077
9449
  return [originalFormActionSetter$LWS, formAction$LWS];
8078
9450
  }
8079
9451
  // istanbul ignore next: ungated return is not reachable in coverage runs
8080
9452
  return [originalFormActionSetter$LWS, originalFormActionSetter$LWS];
8081
9453
  };
8082
9454
  }
9455
+
9456
+ // Uniform guard: applied regardless of the `rel` value. A conditional check
9457
+ // (guarded only on fetch-triggering rel values) is unsafe because the attacker
9458
+ // can set href with an innocuous rel and then flip rel to "preload" to kick
9459
+ // off the request later.
9460
+ function initDistortionHTMLLinkElementHrefSetter$LWS({
9461
+ globalObject: {
9462
+ HTMLLinkElement: HTMLLinkElement$LWS
9463
+ }
9464
+ }) {
9465
+ const originalHrefSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLLinkElement$LWS.prototype, 'href');
9466
+ return function distortionHTMLLinkElementHrefSetter$LWS(record$LWS) {
9467
+ function href$LWS(value$LWS) {
9468
+ const normalized$LWS = toSafeStringValue$LWS(value$LWS);
9469
+ const urlString$LWS = normalized$LWS === '' ? '' : sanitizeURLForElement$LWS(normalized$LWS);
9470
+ if (urlString$LWS !== '' && isGaterEnabledFeature$LWS('changesSince.264')) {
9471
+ const parsedURL$LWS = parseURL$LWS(urlString$LWS);
9472
+ if (!isAllowedEndpointURL$LWS(parsedURL$LWS)) {
9473
+ throw new LockerSecurityError$LWS(`Cannot request disallowed endpoint: ${toSafeTemplateStringValue$LWS(parsedURL$LWS.normalizedURL)}`);
9474
+ }
9475
+ }
9476
+ ReflectApply$LWS$1(HTMLLinkElementProtoHrefSetter$LWS, this, [urlString$LWS]);
9477
+ }
9478
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
9479
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLLinkElement$LWS, 'href', NAMESPACE_DEFAULT$LWS, href$LWS);
9480
+ }
9481
+ return [originalHrefSetter$LWS, href$LWS];
9482
+ };
9483
+ }
8083
9484
  const importRegExp$LWS = /import/i;
8084
9485
  const WARN_MESSAGE$LWS = 'Lightning Web Security: HTMLLinkElement does not allow setting "rel" property to "import" value.';
8085
9486
  function isValidRelValue$LWS(value$LWS) {
@@ -8101,7 +9502,7 @@ function initDistortionHTMLLinkElementRelSetter$LWS({
8101
9502
  }
8102
9503
  const distortionEntry$LWS = [originalRelSetter$LWS, rel$LWS];
8103
9504
  return function distortionHTMLLinkElementRelSetter$LWS(record$LWS) {
8104
- registerAttributeDistortion$LWS(record$LWS, HTMLLinkElement$LWS, 'rel', NAMESPACE_DEFAULT$LWS, rel$LWS);
9505
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLLinkElement$LWS, 'rel', NAMESPACE_DEFAULT$LWS, rel$LWS);
8105
9506
  return distortionEntry$LWS;
8106
9507
  };
8107
9508
  }
@@ -8118,37 +9519,124 @@ function initDistortionHTMLLinkElementRelListSetter$LWS({
8118
9519
  ReflectApply$LWS$1(originalRelListSetter$LWS, this, [string$LWS]);
8119
9520
  return;
8120
9521
  }
8121
- consoleWarn$LWS(WARN_MESSAGE$LWS);
9522
+ consoleWarn$LWS(WARN_MESSAGE$LWS);
9523
+ }];
9524
+ return function distortionHTMLLinkElementRelListSetter$LWS() {
9525
+ return distortionEntry$LWS;
9526
+ };
9527
+ }
9528
+ function initDistortionHTMLMediaElementSrcSetter$LWS({
9529
+ globalObject: {
9530
+ HTMLMediaElement: HTMLMediaElement$LWS
9531
+ }
9532
+ }) {
9533
+ const originalSrcSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLMediaElement$LWS.prototype, 'src');
9534
+ return function distortionHTMLMediaElementSrcSetter$LWS(record$LWS) {
9535
+ function src$LWS(value$LWS) {
9536
+ const normalized$LWS = toSafeStringValue$LWS(value$LWS);
9537
+ const urlString$LWS = normalized$LWS === '' ? '' : sanitizeURLForElement$LWS(normalized$LWS);
9538
+ if (urlString$LWS !== '' && isGaterEnabledFeature$LWS('changesSince.264')) {
9539
+ const parsedURL$LWS = parseURL$LWS(urlString$LWS);
9540
+ if (!isAllowedEndpointURL$LWS(parsedURL$LWS)) {
9541
+ throw new LockerSecurityError$LWS(`Cannot request disallowed endpoint: ${toSafeTemplateStringValue$LWS(parsedURL$LWS.normalizedURL)}`);
9542
+ }
9543
+ }
9544
+ ReflectApply$LWS$1(HTMLMediaElementProtoSrcSetter$LWS, this, [urlString$LWS]);
9545
+ }
9546
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
9547
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLMediaElement$LWS, 'src', NAMESPACE_DEFAULT$LWS, src$LWS);
9548
+ }
9549
+ return [originalSrcSetter$LWS, src$LWS];
9550
+ };
9551
+ }
9552
+ function initDistortionHTMLMetaElementContentGetter$LWS({
9553
+ globalObject: {
9554
+ HTMLMetaElement: HTMLMetaElement$LWS
9555
+ }
9556
+ }) {
9557
+ const originalContentGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLMetaElement$LWS.prototype, 'content');
9558
+ const distortionEntry$LWS = [originalContentGetter$LWS, function content$LWS() {
9559
+ const originalContent$LWS = ReflectApply$LWS$1(originalContentGetter$LWS, this, []);
9560
+ if (isGaterEnabledFeature$LWS('changesSince.262')) {
9561
+ return removeNoncePatterns$LWS(originalContent$LWS);
9562
+ }
9563
+ // istanbul ignore next: ungated return is not reachable in coverage runs
9564
+ return originalContent$LWS;
9565
+ }];
9566
+ return function distortionHTMLMetaElementContentGetter$LWS() {
9567
+ return distortionEntry$LWS;
9568
+ };
9569
+ }
9570
+ function initDistortionHTMLObjectElementContentDocumentGetter$LWS({
9571
+ globalObject: {
9572
+ HTMLObjectElement: HTMLObjectElement$LWS
9573
+ }
9574
+ }) {
9575
+ const originalContentDocumentGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLObjectElement$LWS.prototype, 'contentDocument');
9576
+ const distortionEntry$LWS = [originalContentDocumentGetter$LWS, function contentDocument$LWS() {
9577
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
9578
+ // The <object> element has no sandbox attribute, so its embedded
9579
+ // document runs with full privileges of the parent origin.
9580
+ // Block access to prevent sandbox bypass.
9581
+ return null;
9582
+ }
9583
+ // istanbul ignore next: this line is untested because tests are run with all gates enabled.
9584
+ return ReflectApply$LWS$1(originalContentDocumentGetter$LWS, this, []);
8122
9585
  }];
8123
- return function distortionHTMLLinkElementRelListSetter$LWS() {
9586
+ return function distortionHTMLObjectElementContentDocumentGetter$LWS() {
8124
9587
  return distortionEntry$LWS;
8125
9588
  };
8126
9589
  }
8127
- function initDistortionHTMLMetaElementContentGetter$LWS({
9590
+ function initDistortionHTMLObjectElementContentWindowGetter$LWS({
8128
9591
  globalObject: {
8129
- HTMLMetaElement: HTMLMetaElement$LWS
9592
+ HTMLObjectElement: HTMLObjectElement$LWS
8130
9593
  }
8131
9594
  }) {
8132
- const originalContentGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLMetaElement$LWS.prototype, 'content');
8133
- const distortionEntry$LWS = [originalContentGetter$LWS, function content$LWS() {
8134
- const originalContent$LWS = ReflectApply$LWS$1(originalContentGetter$LWS, this, []);
8135
- if (isGaterEnabledFeature$LWS('changesSince.262')) {
8136
- return removeNoncePatterns$LWS(originalContent$LWS);
9595
+ const originalContentWindowGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLObjectElement$LWS.prototype, 'contentWindow');
9596
+ const distortionEntry$LWS = [originalContentWindowGetter$LWS, function contentWindow$LWS() {
9597
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
9598
+ // The <object> element has no sandbox attribute, so its embedded
9599
+ // document runs with full privileges of the parent origin.
9600
+ // Block access to prevent sandbox bypass.
9601
+ return null;
8137
9602
  }
8138
- // istanbul ignore next: ungated return is not reachable in coverage runs
8139
- return originalContent$LWS;
9603
+ // istanbul ignore next: this line is untested because tests are run with all gates enabled.
9604
+ return ReflectApply$LWS$1(originalContentWindowGetter$LWS, this, []);
8140
9605
  }];
8141
- return function distortionHTMLMetaElementContentGetter$LWS() {
9606
+ return function distortionHTMLObjectElementContentWindowGetter$LWS() {
8142
9607
  return distortionEntry$LWS;
8143
9608
  };
8144
9609
  }
9610
+
9611
+ // MIME types that create a browsing context when used with <object>.
9612
+ // Must match the list in type-setter.ts.
9613
+ const BLOCKED_OBJECT_MIME_TYPES$1$LWS = ['text/html', 'application/xhtml+xml'];
9614
+ const ABOUT_BLANK$LWS = 'about:blank';
8145
9615
  function initDistortionHTMLObjectElementDataSetter$LWS({
8146
9616
  globalObject: {
8147
9617
  HTMLObjectElement: HTMLObjectElement$LWS
8148
9618
  }
8149
9619
  }) {
8150
9620
  const originalDataSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLObjectElement$LWS.prototype, 'data');
9621
+ const originalTypeGetter$LWS = ObjectLookupOwnGetter$LWS$1(HTMLObjectElement$LWS.prototype, 'type');
8151
9622
  function data$LWS(value$LWS) {
9623
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
9624
+ const currentType$LWS = ReflectApply$LWS$1(originalTypeGetter$LWS, this, []);
9625
+ const loweredType$LWS = ReflectApply$LWS$1(StringProtoToLowerCase$LWS, currentType$LWS, []);
9626
+ // Strip MIME parameters before checking (e.g. "text/html;charset=utf-8" → "text/html").
9627
+ const semicolonIndex$LWS = ReflectApply$LWS$1(StringProtoIndexOf$LWS, loweredType$LWS, [';']);
9628
+ const mimeType$LWS = semicolonIndex$LWS === -1 ? loweredType$LWS : ReflectApply$LWS$1(StringProtoTrim$LWS, ReflectApply$LWS$1(StringProtoSlice$LWS$1, loweredType$LWS, [0, semicolonIndex$LWS]), []);
9629
+ // Block if type is explicitly an HTML MIME type.
9630
+ if (BLOCKED_OBJECT_MIME_TYPES$1$LWS.includes(mimeType$LWS)) {
9631
+ throw new LockerSecurityError$LWS('HTMLObjectElement.data cannot be set when type is ' + `"${mimeType$LWS}". HTML content types create an unsandboxed browsing context.`);
9632
+ }
9633
+ // Block if type is empty/absent — the browser will sniff the response
9634
+ // Content-Type, and if it's HTML the embedded document executes scripts
9635
+ // unsandboxed. Only about:blank is safe (empty document, no scripts).
9636
+ if (mimeType$LWS === '' && `${value$LWS}` !== ABOUT_BLANK$LWS) {
9637
+ throw new LockerSecurityError$LWS('HTMLObjectElement.data requires an explicit non-HTML type attribute. ' + 'Without a type, the browser may infer text/html from the response ' + 'and create an unsandboxed browsing context.');
9638
+ }
9639
+ }
8152
9640
  const urlString$LWS = sanitizeURLForElement$LWS(value$LWS);
8153
9641
  if (!isValidURLScheme$LWS(urlString$LWS)) {
8154
9642
  throw new LockerSecurityError$LWS('HTMLObjectElement.data supports http://, https:// schemes, relative urls and about:blank.');
@@ -8161,7 +9649,38 @@ function initDistortionHTMLObjectElementDataSetter$LWS({
8161
9649
  }
8162
9650
  const distortionEntry$LWS = [originalDataSetter$LWS, data$LWS];
8163
9651
  return function distortionHTMLObjectElementDataSetter$LWS(record$LWS) {
8164
- registerAttributeDistortion$LWS(record$LWS, HTMLObjectElement$LWS, 'data', NAMESPACE_DEFAULT$LWS, data$LWS);
9652
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLObjectElement$LWS, 'data', NAMESPACE_DEFAULT$LWS, data$LWS);
9653
+ return distortionEntry$LWS;
9654
+ };
9655
+ }
9656
+
9657
+ // MIME types that create a browsing context when used with <object>.
9658
+ // An embedded browsing context executes scripts with full privileges of the
9659
+ // parent origin — bypassing all LWS sandbox distortions.
9660
+ const BLOCKED_OBJECT_MIME_TYPES$LWS = ['text/html', 'application/xhtml+xml'];
9661
+ function initDistortionHTMLObjectElementTypeSetter$LWS({
9662
+ globalObject: {
9663
+ HTMLObjectElement: HTMLObjectElement$LWS
9664
+ }
9665
+ }) {
9666
+ const originalTypeSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLObjectElement$LWS.prototype, 'type');
9667
+ function type$LWS(value$LWS) {
9668
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
9669
+ const stringValue$LWS = `${value$LWS}`;
9670
+ const lowered$LWS = ReflectApply$LWS$1(StringProtoToLowerCase$LWS, stringValue$LWS, []);
9671
+ // Strip MIME parameters (e.g. "text/html;charset=utf-8" → "text/html").
9672
+ // Per RFC 2045 §5.1, parameters follow `;`. We check the type/subtype prefix.
9673
+ const semicolonIndex$LWS = ReflectApply$LWS$1(StringProtoIndexOf$LWS, lowered$LWS, [';']);
9674
+ const mimeType$LWS = semicolonIndex$LWS === -1 ? lowered$LWS : ReflectApply$LWS$1(StringProtoTrim$LWS, ReflectApply$LWS$1(StringProtoSlice$LWS$1, lowered$LWS, [0, semicolonIndex$LWS]), []);
9675
+ if (BLOCKED_OBJECT_MIME_TYPES$LWS.includes(mimeType$LWS)) {
9676
+ throw new LockerSecurityError$LWS(`HTMLObjectElement.type cannot be set to "${mimeType$LWS}". ` + 'HTML content types create an unsandboxed browsing context.');
9677
+ }
9678
+ }
9679
+ ReflectApply$LWS$1(originalTypeSetter$LWS, this, [value$LWS]);
9680
+ }
9681
+ const distortionEntry$LWS = [originalTypeSetter$LWS, type$LWS];
9682
+ return function distortionHTMLObjectElementTypeSetter$LWS(record$LWS) {
9683
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLObjectElement$LWS, 'type', NAMESPACE_DEFAULT$LWS, type$LWS);
8165
9684
  return distortionEntry$LWS;
8166
9685
  };
8167
9686
  }
@@ -8230,7 +9749,7 @@ function initDistortionHTMLScriptElementInnerTextSetter$LWS({
8230
9749
  };
8231
9750
  }
8232
9751
  const descriptorCaches$LWS = toSafeWeakMap$LWS$1(new WeakMapCtor$LWS$1());
8233
- function createBlockedAttributeDistortionFactoryInitializer$LWS(Ctor$LWS, ctorName$LWS, attributeName$LWS) {
9752
+ function createBlockedAttributeSetterDistortionFactoryInitializer$LWS(Ctor$LWS, ctorName$LWS, attributeName$LWS) {
8234
9753
  return function initDistortionBlockedAttribute$LWS() {
8235
9754
  const enquotedAttributeName$LWS = enquote$LWS(attributeName$LWS);
8236
9755
  const distortionName$LWS = `blocked${capitalizeFirstChar$LWS(attributeName$LWS)}Attribute`;
@@ -8244,7 +9763,7 @@ function createBlockedAttributeDistortionFactoryInitializer$LWS(Ctor$LWS, ctorNa
8244
9763
  }
8245
9764
  };
8246
9765
  return function distortionBlockedAttribute$LWS(record$LWS) {
8247
- registerAttributeDistortion$LWS(record$LWS, Ctor$LWS, attributeName$LWS, NAMESPACE_DEFAULT$LWS, distortion$LWS);
9766
+ registerAttributeSetterDistortion$LWS(record$LWS, Ctor$LWS, attributeName$LWS, NAMESPACE_DEFAULT$LWS, distortion$LWS);
8248
9767
  };
8249
9768
  };
8250
9769
  }
@@ -8289,14 +9808,48 @@ function createValueThrowerFactoryInitializer$LWS(proto$LWS, key$LWS) {
8289
9808
  return valueThrowerDistortionFactory$LWS;
8290
9809
  };
8291
9810
  }
8292
- function addBlockedAttributeDistortionFactoryInitializers$LWS(Ctor$LWS, ctorName$LWS, attributes$LWS, factoryInitializers$LWS) {
9811
+ function addBlockedAttributeSetterDistortionFactoryInitializers$LWS(Ctor$LWS, ctorName$LWS, attributes$LWS, factoryInitializers$LWS) {
9812
+ let {
9813
+ length: factoryInitializersOffset$LWS
9814
+ } = factoryInitializers$LWS;
9815
+ for (let i$LWS = 0, {
9816
+ length: length$LWS
9817
+ } = attributes$LWS; i$LWS < length$LWS; i$LWS += 1) {
9818
+ factoryInitializers$LWS[factoryInitializersOffset$LWS++] = createBlockedAttributeSetterDistortionFactoryInitializer$LWS(Ctor$LWS, ctorName$LWS, attributes$LWS[i$LWS]);
9819
+ }
9820
+ }
9821
+ // Read-side counterpart of createBlockedAttributeSetterDistortionFactoryInitializer:
9822
+ // produce a factory that registers a thrower in the read-side getter registry
9823
+ // for `(Ctor, attributeName)`. When sandboxed code reads the attribute via any
9824
+ // of the distortion-covered read paths (Element.getAttribute family,
9825
+ // NamedNodeMap.getNamedItem family, Attr.value getter), the registered thrower
9826
+ // fires and refuses the read.
9827
+ function createBlockedAttributeGetterDistortionFactoryInitializer$LWS(Ctor$LWS, attributeName$LWS) {
9828
+ return function initDistortionBlockedAttributeGetter$LWS() {
9829
+ const enquotedAttributeName$LWS = enquote$LWS(attributeName$LWS);
9830
+ const distortionName$LWS = `blocked${capitalizeFirstChar$LWS(attributeName$LWS)}AttributeGetter`;
9831
+ const {
9832
+ [distortionName$LWS]: thrower$LWS
9833
+ } = {
9834
+ [distortionName$LWS]: () => {
9835
+ // Match the message used by the previous blockAccessToNonce
9836
+ // inline call so existing assertions remain valid.
9837
+ throw new LockerSecurityError$LWS(`Attribute ${enquotedAttributeName$LWS} not accessible`);
9838
+ }
9839
+ };
9840
+ return function distortionBlockedAttributeGetter$LWS(record$LWS) {
9841
+ registerAttributeGetterDistortion$LWS(record$LWS, Ctor$LWS, attributeName$LWS, NAMESPACE_DEFAULT$LWS, thrower$LWS);
9842
+ };
9843
+ };
9844
+ }
9845
+ function addBlockedAttributeGetterDistortionFactoryInitializers$LWS(Ctor$LWS, attributes$LWS, factoryInitializers$LWS) {
8293
9846
  let {
8294
9847
  length: factoryInitializersOffset$LWS
8295
9848
  } = factoryInitializers$LWS;
8296
9849
  for (let i$LWS = 0, {
8297
9850
  length: length$LWS
8298
9851
  } = attributes$LWS; i$LWS < length$LWS; i$LWS += 1) {
8299
- factoryInitializers$LWS[factoryInitializersOffset$LWS++] = createBlockedAttributeDistortionFactoryInitializer$LWS(Ctor$LWS, ctorName$LWS, attributes$LWS[i$LWS]);
9852
+ factoryInitializers$LWS[factoryInitializersOffset$LWS++] = createBlockedAttributeGetterDistortionFactoryInitializer$LWS(Ctor$LWS, attributes$LWS[i$LWS]);
8300
9853
  }
8301
9854
  }
8302
9855
  function addBlockedPropertyDistortionFactoryInitializers$LWS({
@@ -8437,7 +9990,7 @@ function initDistortionHTMLScriptElementSrcSetter$LWS({
8437
9990
  } = ReflectGetOwnPropertyDescriptor$LWS(HTMLScriptElement$LWS.prototype, 'src');
8438
9991
  return function distortionHTMLScriptElementSrcSetter$LWS(record$LWS) {
8439
9992
  const src$LWS = createScriptDistortion$LWS(record$LWS, 'src');
8440
- registerAttributeDistortion$LWS(record$LWS, HTMLScriptElement$LWS, 'src', NAMESPACE_DEFAULT$LWS, src$LWS);
9993
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLScriptElement$LWS, 'src', NAMESPACE_DEFAULT$LWS, src$LWS);
8441
9994
  return [originalSrcSetter$LWS, src$LWS];
8442
9995
  };
8443
9996
  }
@@ -8552,6 +10105,72 @@ function initDistortionHTMLScriptElementTextContentSetter$LWS({
8552
10105
  }];
8553
10106
  };
8554
10107
  }
10108
+ function initDistortionHTMLSourceElementSrcSetter$LWS({
10109
+ globalObject: {
10110
+ HTMLSourceElement: HTMLSourceElement$LWS
10111
+ }
10112
+ }) {
10113
+ const originalSrcSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLSourceElement$LWS.prototype, 'src');
10114
+ return function distortionHTMLSourceElementSrcSetter$LWS(record$LWS) {
10115
+ function src$LWS(value$LWS) {
10116
+ const normalized$LWS = toSafeStringValue$LWS(value$LWS);
10117
+ const urlString$LWS = normalized$LWS === '' ? '' : sanitizeURLForElement$LWS(normalized$LWS);
10118
+ if (urlString$LWS !== '' && isGaterEnabledFeature$LWS('changesSince.264')) {
10119
+ const parsedURL$LWS = parseURL$LWS(urlString$LWS);
10120
+ if (!isAllowedEndpointURL$LWS(parsedURL$LWS)) {
10121
+ throw new LockerSecurityError$LWS(`Cannot request disallowed endpoint: ${toSafeTemplateStringValue$LWS(parsedURL$LWS.normalizedURL)}`);
10122
+ }
10123
+ }
10124
+ ReflectApply$LWS$1(HTMLSourceElementProtoSrcSetter$LWS, this, [urlString$LWS]);
10125
+ }
10126
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
10127
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLSourceElement$LWS, 'src', NAMESPACE_DEFAULT$LWS, src$LWS);
10128
+ }
10129
+ return [originalSrcSetter$LWS, src$LWS];
10130
+ };
10131
+ }
10132
+ function initDistortionHTMLSourceElementSrcsetSetter$LWS({
10133
+ globalObject: {
10134
+ HTMLSourceElement: HTMLSourceElement$LWS
10135
+ }
10136
+ }) {
10137
+ const originalSrcsetSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLSourceElement$LWS.prototype, 'srcset');
10138
+ return function distortionHTMLSourceElementSrcsetSetter$LWS(record$LWS) {
10139
+ function srcset$LWS(value$LWS) {
10140
+ const normalized$LWS = toSafeStringValue$LWS(value$LWS);
10141
+ const finalValue$LWS = normalized$LWS !== '' && isGaterEnabledFeature$LWS('changesSince.264') ? sanitizeSrcsetAndValidateEndpoints$LWS(normalized$LWS) : normalized$LWS;
10142
+ ReflectApply$LWS$1(HTMLSourceElementProtoSrcsetSetter$LWS, this, [finalValue$LWS]);
10143
+ }
10144
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
10145
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLSourceElement$LWS, 'srcset', NAMESPACE_DEFAULT$LWS, srcset$LWS);
10146
+ }
10147
+ return [originalSrcsetSetter$LWS, srcset$LWS];
10148
+ };
10149
+ }
10150
+ function initDistortionHTMLTrackElementSrcSetter$LWS({
10151
+ globalObject: {
10152
+ HTMLTrackElement: HTMLTrackElement$LWS
10153
+ }
10154
+ }) {
10155
+ const originalSrcSetter$LWS = ObjectLookupOwnSetter$LWS(HTMLTrackElement$LWS.prototype, 'src');
10156
+ return function distortionHTMLTrackElementSrcSetter$LWS(record$LWS) {
10157
+ function src$LWS(value$LWS) {
10158
+ const normalized$LWS = toSafeStringValue$LWS(value$LWS);
10159
+ const urlString$LWS = normalized$LWS === '' ? '' : sanitizeURLForElement$LWS(normalized$LWS);
10160
+ if (urlString$LWS !== '' && isGaterEnabledFeature$LWS('changesSince.264')) {
10161
+ const parsedURL$LWS = parseURL$LWS(urlString$LWS);
10162
+ if (!isAllowedEndpointURL$LWS(parsedURL$LWS)) {
10163
+ throw new LockerSecurityError$LWS(`Cannot request disallowed endpoint: ${toSafeTemplateStringValue$LWS(parsedURL$LWS.normalizedURL)}`);
10164
+ }
10165
+ }
10166
+ ReflectApply$LWS$1(HTMLTrackElementProtoSrcSetter$LWS, this, [urlString$LWS]);
10167
+ }
10168
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
10169
+ registerAttributeSetterDistortion$LWS(record$LWS, HTMLTrackElement$LWS, 'src', NAMESPACE_DEFAULT$LWS, src$LWS);
10170
+ }
10171
+ return [originalSrcSetter$LWS, src$LWS];
10172
+ };
10173
+ }
8555
10174
  function initDistortionIDBFactoryDatabases$LWS({
8556
10175
  globalObject: {
8557
10176
  IDBFactory: IDBFactory$LWS
@@ -8808,6 +10427,165 @@ function initDistortionMutationObserverObserve$LWS({
8808
10427
  return distortionEntry$LWS;
8809
10428
  };
8810
10429
  }
10430
+ function initDistortionNamedNodeMapGetNamedItem$LWS({
10431
+ globalObject: {
10432
+ document: sandboxDocument$LWS,
10433
+ NamedNodeMap: {
10434
+ prototype: {
10435
+ getNamedItem: originalGetNamedItem$LWS
10436
+ }
10437
+ }
10438
+ }
10439
+ }) {
10440
+ return function distortionNamedNodeMapGetNamedItem$LWS(record$LWS) {
10441
+ return [originalGetNamedItem$LWS, function getNamedItem$LWS(...args$LWS) {
10442
+ const {
10443
+ length: length$LWS
10444
+ } = args$LWS;
10445
+ if (isGaterEnabledFeature$LWS('changesSince.264') && length$LWS > 0) {
10446
+ // Guard against TOCTOU attacks: force the native call
10447
+ // to see the same value our checks ran against.
10448
+ const coerced$LWS = toSafeStringValue$LWS(args$LWS[0]);
10449
+ args$LWS[0] = coerced$LWS;
10450
+ const element$LWS = getOwnerElement$LWS(this);
10451
+ if (element$LWS !== undefined) {
10452
+ // Consult the read-side registry. A throwing
10453
+ // registered getter (e.g. nonce) refuses the
10454
+ // read by propagating its exception. A value-
10455
+ // substituting getter (e.g. iframe.src pending
10456
+ // URL) returns a string; if the native attribute
10457
+ // store has no Attr for this name, synthesize a
10458
+ // detached Attr carrying the substituted value
10459
+ // so sandbox code can read .value as expected.
10460
+ // If the native store already has an Attr,
10461
+ // prefer it.
10462
+ const override$LWS = getAttributeGetterDistortion$LWS(record$LWS, element$LWS, coerced$LWS);
10463
+ if (override$LWS !== undefined) {
10464
+ const overrideValue$LWS = ReflectApply$LWS$1(override$LWS, element$LWS, []);
10465
+ if (overrideValue$LWS !== null && overrideValue$LWS !== undefined) {
10466
+ const nativeAttr$LWS = ReflectApply$LWS$1(originalGetNamedItem$LWS, this, args$LWS);
10467
+ if (nativeAttr$LWS !== null) {
10468
+ return nativeAttr$LWS;
10469
+ }
10470
+ const synth$LWS = ReflectApply$LWS$1(DocumentProtoCreateAttribute$LWS, sandboxDocument$LWS, [coerced$LWS]);
10471
+ synth$LWS.value = overrideValue$LWS;
10472
+ return synth$LWS;
10473
+ }
10474
+ }
10475
+ }
10476
+ }
10477
+ return ReflectApply$LWS$1(originalGetNamedItem$LWS, this, args$LWS);
10478
+ }];
10479
+ };
10480
+ }
10481
+ function initDistortionNamedNodeMapGetNamedItemNS$LWS({
10482
+ globalObject: {
10483
+ document: sandboxDocument$LWS,
10484
+ NamedNodeMap: {
10485
+ prototype: {
10486
+ getNamedItemNS: originalGetNamedItemNS$LWS
10487
+ }
10488
+ }
10489
+ }
10490
+ }) {
10491
+ return function distortionNamedNodeMapGetNamedItemNS$LWS(record$LWS) {
10492
+ return [originalGetNamedItemNS$LWS, function getNamedItemNS$LWS(...args$LWS) {
10493
+ const {
10494
+ length: length$LWS
10495
+ } = args$LWS;
10496
+ if (isGaterEnabledFeature$LWS('changesSince.264') && length$LWS >= 2) {
10497
+ // Guard against TOCTOU attacks: force the native call
10498
+ // to see the same values our checks ran against.
10499
+ const coercedNS$LWS = args$LWS[0] === null || args$LWS[0] === undefined ? args$LWS[0] : toSafeStringValue$LWS(args$LWS[0]);
10500
+ const coercedName$LWS = toSafeStringValue$LWS(args$LWS[1]);
10501
+ args$LWS[0] = coercedNS$LWS;
10502
+ args$LWS[1] = coercedName$LWS;
10503
+ const element$LWS = getOwnerElement$LWS(this);
10504
+ if (element$LWS !== undefined) {
10505
+ const ns$LWS = normalizeNamespace$LWS(coercedNS$LWS);
10506
+ const override$LWS = getAttributeGetterDistortion$LWS(record$LWS, element$LWS, coercedName$LWS, ns$LWS);
10507
+ if (override$LWS !== undefined) {
10508
+ const overrideValue$LWS = ReflectApply$LWS$1(override$LWS, element$LWS, []);
10509
+ if (overrideValue$LWS !== null && overrideValue$LWS !== undefined) {
10510
+ const nativeAttr$LWS = ReflectApply$LWS$1(originalGetNamedItemNS$LWS, this, args$LWS);
10511
+ if (nativeAttr$LWS !== null) {
10512
+ return nativeAttr$LWS;
10513
+ }
10514
+ const synth$LWS = ReflectApply$LWS$1(DocumentProtoCreateAttributeNS$LWS, sandboxDocument$LWS, [ns$LWS, coercedName$LWS]);
10515
+ synth$LWS.value = overrideValue$LWS;
10516
+ return synth$LWS;
10517
+ }
10518
+ }
10519
+ }
10520
+ }
10521
+ return ReflectApply$LWS$1(originalGetNamedItemNS$LWS, this, args$LWS);
10522
+ }];
10523
+ };
10524
+ }
10525
+ const SANDBOX_ATTR$1$LWS = 'sandbox';
10526
+ function initDistortionNamedNodeMapRemoveNamedItem$LWS({
10527
+ globalObject: {
10528
+ HTMLIFrameElement: HTMLIFrameElement$LWS,
10529
+ NamedNodeMap: {
10530
+ prototype: {
10531
+ removeNamedItem: originalRemoveNamedItem$LWS
10532
+ }
10533
+ }
10534
+ }
10535
+ }) {
10536
+ const distortionEntry$LWS = [originalRemoveNamedItem$LWS, function removeNamedItem$LWS(...args$LWS) {
10537
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
10538
+ if (args$LWS.length > 0) {
10539
+ const attrName$LWS = ReflectApply$LWS$1(StringProtoToLowerCase$LWS, toSafeStringValue$LWS(args$LWS[0]), []);
10540
+ if (attrName$LWS === SANDBOX_ATTR$1$LWS) {
10541
+ // getOwnerElement returns undefined if the Element.attributes
10542
+ // getter distortion hasn't run yet; in that case the instanceof
10543
+ // check short-circuits and we fall through to the original method.
10544
+ const element$LWS = getOwnerElement$LWS(this);
10545
+ if (element$LWS instanceof HTMLIFrameElement$LWS) {
10546
+ throw new LockerSecurityError$LWS("Cannot remove 'sandbox' attribute from HTMLIFrameElement.");
10547
+ }
10548
+ }
10549
+ }
10550
+ }
10551
+ return ReflectApply$LWS$1(originalRemoveNamedItem$LWS, this, args$LWS);
10552
+ }];
10553
+ return function distortionNamedNodeMapRemoveNamedItem$LWS() {
10554
+ return distortionEntry$LWS;
10555
+ };
10556
+ }
10557
+ const SANDBOX_ATTR$LWS = 'sandbox';
10558
+ function initDistortionNamedNodeMapRemoveNamedItemNS$LWS({
10559
+ globalObject: {
10560
+ HTMLIFrameElement: HTMLIFrameElement$LWS,
10561
+ NamedNodeMap: {
10562
+ prototype: {
10563
+ removeNamedItemNS: originalRemoveNamedItemNS$LWS
10564
+ }
10565
+ }
10566
+ }
10567
+ }) {
10568
+ const distortionEntry$LWS = [originalRemoveNamedItemNS$LWS, function removeNamedItemNS$LWS(...args$LWS) {
10569
+ if (isGaterEnabledFeature$LWS('changesSince.264')) {
10570
+ if (args$LWS.length > 1) {
10571
+ const attrName$LWS = ReflectApply$LWS$1(StringProtoToLowerCase$LWS, toSafeStringValue$LWS(args$LWS[1]), []);
10572
+ if (attrName$LWS === SANDBOX_ATTR$LWS) {
10573
+ // getOwnerElement returns undefined if the Element.attributes
10574
+ // getter distortion hasn't run yet; in that case the instanceof
10575
+ // check short-circuits and we fall through to the original method.
10576
+ const element$LWS = getOwnerElement$LWS(this);
10577
+ if (element$LWS instanceof HTMLIFrameElement$LWS) {
10578
+ throw new LockerSecurityError$LWS("Cannot remove 'sandbox' attribute from HTMLIFrameElement.");
10579
+ }
10580
+ }
10581
+ }
10582
+ }
10583
+ return ReflectApply$LWS$1(originalRemoveNamedItemNS$LWS, this, args$LWS);
10584
+ }];
10585
+ return function distortionNamedNodeMapRemoveNamedItemNS$LWS() {
10586
+ return distortionEntry$LWS;
10587
+ };
10588
+ }
8811
10589
  function initDistortionNamedNodeMapSetNamedItem$LWS({
8812
10590
  globalObject: {
8813
10591
  Attr: Attr$LWS,
@@ -8886,6 +10664,27 @@ function initDistortionNavigatorServiceWorkerGetter$LWS({
8886
10664
  return distortionEntry$LWS;
8887
10665
  };
8888
10666
  }
10667
+ function initDistortionNodeGetRootNode$LWS({
10668
+ globalObject: {
10669
+ Node: Node$LWS,
10670
+ ShadowRoot: ShadowRoot$LWS,
10671
+ document: document$LWS
10672
+ }
10673
+ }) {
10674
+ const originalGetRootNode$LWS = ObjectLookupOwnValue$LWS(Node$LWS.prototype, 'getRootNode');
10675
+ return function distortionNodeGetRootNode$LWS({
10676
+ key: key$LWS
10677
+ }) {
10678
+ const distortionEntry$LWS = [originalGetRootNode$LWS, function getRootNode$LWS(...args$LWS) {
10679
+ const realRoot$LWS = ReflectApply$LWS$1(originalGetRootNode$LWS, this, args$LWS);
10680
+ if (isGaterEnabledFeature$LWS('changesSince.264') && realRoot$LWS instanceof ShadowRoot$LWS && !isShadowRootAccessibleInThisSandbox$LWS(key$LWS, realRoot$LWS)) {
10681
+ return document$LWS;
10682
+ }
10683
+ return realRoot$LWS;
10684
+ }];
10685
+ return distortionEntry$LWS;
10686
+ };
10687
+ }
8889
10688
  const {
8890
10689
  isSharedElement: isSharedElement$k$LWS,
8891
10690
  isAllowedSharedElementChild: isAllowedSharedElementChild$1$LWS
@@ -8942,7 +10741,7 @@ function initDistortionNodeValueSetter$LWS({
8942
10741
  const attrName$LWS = ReflectApply$LWS$1(AttrProtoNameGetter$LWS, this, []);
8943
10742
  const attrNamespace$LWS = ReflectApply$LWS$1(AttrProtoNamespaceURIGetter$LWS, this, []);
8944
10743
  const normalizedNamespace$LWS = normalizeNamespace$LWS(attrNamespace$LWS);
8945
- const distortion$LWS = getAttributeDistortion$LWS(record$LWS, ownerEl$LWS, attrName$LWS, normalizedNamespace$LWS);
10744
+ const distortion$LWS = getAttributeSetterDistortion$LWS(record$LWS, ownerEl$LWS, attrName$LWS, normalizedNamespace$LWS);
8946
10745
  // istanbul ignore next: needs default platform behavior test
8947
10746
  if (distortion$LWS) {
8948
10747
  ReflectApply$LWS$1(distortion$LWS, ownerEl$LWS, [value$LWS]);
@@ -8954,6 +10753,56 @@ function initDistortionNodeValueSetter$LWS({
8954
10753
  }];
8955
10754
  };
8956
10755
  }
10756
+ function initDistortionNodeParentElementGetter$LWS({
10757
+ globalObject: {
10758
+ Node: Node$LWS,
10759
+ ShadowRoot: ShadowRoot$LWS
10760
+ }
10761
+ }) {
10762
+ const originalParentElementGetter$LWS = ObjectLookupOwnGetter$LWS$1(Node$LWS.prototype, 'parentElement');
10763
+ const originalGetRootNode$LWS = ObjectLookupOwnValue$LWS(Node$LWS.prototype, 'getRootNode');
10764
+ return function distortionNodeParentElementGetter$LWS({
10765
+ key: key$LWS
10766
+ }) {
10767
+ const distortionEntry$LWS = [originalParentElementGetter$LWS, function parentElement$LWS() {
10768
+ const parent$LWS = ReflectApply$LWS$1(originalParentElementGetter$LWS, this, []);
10769
+ if (parent$LWS === null || !isGaterEnabledFeature$LWS('changesSince.264')) {
10770
+ return parent$LWS;
10771
+ }
10772
+ const parentRoot$LWS = ReflectApply$LWS$1(originalGetRootNode$LWS, parent$LWS, []);
10773
+ if (parentRoot$LWS instanceof ShadowRoot$LWS && !isShadowRootAccessibleInThisSandbox$LWS(key$LWS, parentRoot$LWS)) {
10774
+ return null;
10775
+ }
10776
+ return parent$LWS;
10777
+ }];
10778
+ return distortionEntry$LWS;
10779
+ };
10780
+ }
10781
+ function initDistortionNodeParentNodeGetter$LWS({
10782
+ globalObject: {
10783
+ Node: Node$LWS,
10784
+ ShadowRoot: ShadowRoot$LWS
10785
+ }
10786
+ }) {
10787
+ const originalParentNodeGetter$LWS = ObjectLookupOwnGetter$LWS$1(Node$LWS.prototype, 'parentNode');
10788
+ const originalGetRootNode$LWS = ObjectLookupOwnValue$LWS(Node$LWS.prototype, 'getRootNode');
10789
+ return function distortionNodeParentNodeGetter$LWS({
10790
+ key: key$LWS
10791
+ }) {
10792
+ const distortionEntry$LWS = [originalParentNodeGetter$LWS, function parentNode$LWS() {
10793
+ const parent$LWS = ReflectApply$LWS$1(originalParentNodeGetter$LWS, this, []);
10794
+ if (parent$LWS === null || !isGaterEnabledFeature$LWS('changesSince.264')) {
10795
+ return parent$LWS;
10796
+ }
10797
+ const parentRoot$LWS = ReflectApply$LWS$1(originalGetRootNode$LWS, parent$LWS, []);
10798
+ if (parentRoot$LWS instanceof ShadowRoot$LWS && !isShadowRootAccessibleInThisSandbox$LWS(key$LWS, parentRoot$LWS)) {
10799
+ return null;
10800
+ }
10801
+ return parent$LWS;
10802
+ }];
10803
+ return distortionEntry$LWS;
10804
+ };
10805
+ }
8957
10806
  const {
8958
10807
  isSharedElement: isSharedElement$j$LWS
8959
10808
  } = rootValidator$LWS;
@@ -9093,7 +10942,7 @@ function initDistortionNodeTextContentSetter$LWS({
9093
10942
  const attrName$LWS = ReflectApply$LWS$1(AttrProtoNameGetter$LWS, this, []);
9094
10943
  const attrNamespace$LWS = ReflectApply$LWS$1(AttrProtoNamespaceURIGetter$LWS, this, []);
9095
10944
  const normalizedNamespace$LWS = normalizeNamespace$LWS(attrNamespace$LWS);
9096
- const distortion$LWS = getAttributeDistortion$LWS(record$LWS, ownerEl$LWS, attrName$LWS, normalizedNamespace$LWS);
10945
+ const distortion$LWS = getAttributeSetterDistortion$LWS(record$LWS, ownerEl$LWS, attrName$LWS, normalizedNamespace$LWS);
9097
10946
  // istanbul ignore next: needs default platform behavior test
9098
10947
  if (distortion$LWS) {
9099
10948
  ReflectApply$LWS$1(distortion$LWS, ownerEl$LWS, [valueAsString$LWS]);
@@ -9729,6 +11578,9 @@ function initDistortionRangeCloneRange$LWS({
9729
11578
  return distortionEntry$LWS;
9730
11579
  };
9731
11580
  }
11581
+ const {
11582
+ isIframeSrcdocScriptAttack: isIframeSrcdocScriptAttack$2$LWS
11583
+ } = rootValidator$LWS;
9732
11584
  function initDistortionRangeCreateContextualFragment$LWS({
9733
11585
  document: document$LWS,
9734
11586
  globalObject: {
@@ -9754,6 +11606,9 @@ function initDistortionRangeCreateContextualFragment$LWS({
9754
11606
  // for association to this sandbox.
9755
11607
  setCustomElementsRegistry$LWS(document$LWS, key$LWS);
9756
11608
  args$LWS[0] = lwsInternalPolicy$LWS.createHTML(tagString$LWS, key$LWS, ContentType$LWS.HTML);
11609
+ if (isGaterEnabledFeature$LWS('changesSince.264') && isIframeSrcdocScriptAttack$2$LWS(args$LWS[0])) {
11610
+ throw new LockerSecurityError$LWS(`Cannot 'createContextualFragment' using an unsecure ${toSafeTemplateStringValue$LWS(args$LWS[0])}.`);
11611
+ }
9757
11612
  }
9758
11613
  }
9759
11614
  return ReflectApply$LWS$1(originalCreateContextualFragment$LWS, this, args$LWS);
@@ -9993,6 +11848,63 @@ function initDistortionRangeToString$LWS({
9993
11848
  return distortionEntry$LWS;
9994
11849
  };
9995
11850
  }
11851
+
11852
+ // W-22602807: distort an iframe contentWindow realm's Reflect.apply.
11853
+ // See Function/cross-realm-invocation.ts for the threat model.
11854
+ //
11855
+ // Unlike Function.prototype.apply, the callee is the FIRST ARGUMENT (not
11856
+ // `this`) and the invocation never routes through Function.prototype.call, so
11857
+ // it is an independent doorway that must be distorted separately.
11858
+ function initDistortionReflectApply$LWS({
11859
+ globalObject: {
11860
+ Reflect: {
11861
+ apply: originalReflectApply$LWS
11862
+ }
11863
+ }
11864
+ }) {
11865
+ return function distortionReflectApply$LWS({
11866
+ globalObject: globalObject$LWS,
11867
+ root: root$LWS
11868
+ }) {
11869
+ if (!getDistortableFrameElement$LWS(globalObject$LWS)) {
11870
+ return undefined;
11871
+ }
11872
+ return [originalReflectApply$LWS, function apply$LWS(target$LWS, thisArg$LWS, argsArray$LWS) {
11873
+ return ReflectApply$LWS$1(substituteDistortedCallee$LWS(root$LWS, target$LWS), thisArg$LWS, argsArray$LWS == null ? [] : argsArray$LWS);
11874
+ }];
11875
+ };
11876
+ }
11877
+
11878
+ // W-22602807: distort an iframe contentWindow realm's Reflect.construct.
11879
+ // See Function/cross-realm-invocation.ts for the threat model.
11880
+ //
11881
+ // Construct semantics (not call): the callee is the FIRST ARGUMENT and is
11882
+ // invoked as a constructor. Substitute it for its distorted counterpart, then
11883
+ // construct with the sandbox-realm Reflect.construct, preserving the optional
11884
+ // newTarget argument.
11885
+ function initDistortionReflectConstruct$LWS({
11886
+ globalObject: {
11887
+ Reflect: {
11888
+ construct: originalReflectConstruct$LWS
11889
+ }
11890
+ }
11891
+ }) {
11892
+ return function distortionReflectConstruct$LWS({
11893
+ globalObject: globalObject$LWS,
11894
+ root: root$LWS
11895
+ }) {
11896
+ if (!getDistortableFrameElement$LWS(globalObject$LWS)) {
11897
+ return undefined;
11898
+ }
11899
+ return [originalReflectConstruct$LWS, function construct$LWS(target$LWS, argsArray$LWS, newTarget$LWS) {
11900
+ const substituted$LWS = substituteDistortedCallee$LWS(root$LWS, target$LWS);
11901
+ if (arguments.length > 2) {
11902
+ return ReflectConstruct$LWS(substituted$LWS, argsArray$LWS == null ? [] : argsArray$LWS, newTarget$LWS);
11903
+ }
11904
+ return ReflectConstruct$LWS(substituted$LWS, argsArray$LWS == null ? [] : argsArray$LWS);
11905
+ }];
11906
+ };
11907
+ }
9996
11908
  function initDistortionReportingObserverCtor$LWS({
9997
11909
  globalObject: {
9998
11910
  ReportingObserver: originalReportingObserverCtor$LWS
@@ -10640,7 +12552,7 @@ function createDistortionStorageFactoryInitializer$LWS(storageName$LWS) {
10640
12552
  try {
10641
12553
  originalStorageObject$LWS = globalObject$LWS[storageName$LWS];
10642
12554
  // eslint-disable-next-line no-empty
10643
- } catch (_unused3$LWS) {}
12555
+ } catch (_unused4$LWS) {}
10644
12556
  // istanbul ignore if: currently unreachable via tests
10645
12557
  if (!isObject$LWS$1(originalStorageObject$LWS)) {
10646
12558
  return noop$LWS$1;
@@ -10782,7 +12694,7 @@ function initDistortionSVGAnimateElementAttributeNameAttribute$LWS({
10782
12694
  const originalAttributeValue$LWS = ReflectApply$LWS$1(ElementProtoGetAttribute$LWS, el$LWS, [attrName$LWS]);
10783
12695
  // istanbul ignore else: needs default platform behavior test
10784
12696
  if (originalAttributeValue$LWS) {
10785
- const distortion$LWS = getAttributeDistortion$LWS(record$LWS, el$LWS, attrName$LWS);
12697
+ const distortion$LWS = getAttributeSetterDistortion$LWS(record$LWS, el$LWS, attrName$LWS);
10786
12698
  // istanbul ignore else: needs default platform behavior test
10787
12699
  if (distortion$LWS) {
10788
12700
  ReflectApply$LWS$1(distortion$LWS, el$LWS, [originalAttributeValue$LWS]);
@@ -10790,7 +12702,7 @@ function initDistortionSVGAnimateElementAttributeNameAttribute$LWS({
10790
12702
  }
10791
12703
  }
10792
12704
  }
10793
- registerAttributeDistortion$LWS(record$LWS, SVGAnimateElement$LWS, 'attributeName', NAMESPACE_DEFAULT$LWS, function attributeName$LWS(value$LWS) {
12705
+ registerAttributeSetterDistortion$LWS(record$LWS, SVGAnimateElement$LWS, 'attributeName', NAMESPACE_DEFAULT$LWS, function attributeName$LWS(value$LWS) {
10794
12706
  ReflectApply$LWS$1(originalSetAttribute$LWS, this, ['attributeName', value$LWS]);
10795
12707
  if (value$LWS === 'href') {
10796
12708
  distortAttribute$LWS(this, 'from');
@@ -10817,7 +12729,7 @@ function initDistortionSVGAnimateElementFromAttribute$LWS({
10817
12729
  ReflectApply$LWS$1(originalSetAttribute$LWS, this, ['from', value$LWS]);
10818
12730
  }
10819
12731
  return function distortionSVGAnimateElementFromAttribute$LWS(record$LWS) {
10820
- registerAttributeDistortion$LWS(record$LWS, SVGAnimateElement$LWS, 'from', NAMESPACE_DEFAULT$LWS, from$LWS);
12732
+ registerAttributeSetterDistortion$LWS(record$LWS, SVGAnimateElement$LWS, 'from', NAMESPACE_DEFAULT$LWS, from$LWS);
10821
12733
  };
10822
12734
  }
10823
12735
  function initDistortionSVGAnimateElementToAttribute$LWS({
@@ -10837,7 +12749,7 @@ function initDistortionSVGAnimateElementToAttribute$LWS({
10837
12749
  ReflectApply$LWS$1(originalSetAttribute$LWS, this, ['to', value$LWS]);
10838
12750
  }
10839
12751
  return function distortionSVGAnimateElementToAttribute$LWS(record$LWS) {
10840
- registerAttributeDistortion$LWS(record$LWS, SVGAnimateElement$LWS, 'to', NAMESPACE_DEFAULT$LWS, to$LWS);
12752
+ registerAttributeSetterDistortion$LWS(record$LWS, SVGAnimateElement$LWS, 'to', NAMESPACE_DEFAULT$LWS, to$LWS);
10841
12753
  };
10842
12754
  }
10843
12755
  function initDistortionSVGAnimateElementValuesAttribute$LWS({
@@ -10865,7 +12777,7 @@ function initDistortionSVGAnimateElementValuesAttribute$LWS({
10865
12777
  ReflectApply$LWS$1(originalSetAttribute$LWS, this, ['values', returnValues$LWS]);
10866
12778
  }
10867
12779
  return function distortionSVGAnimateElementValuesAttribute$LWS(record$LWS) {
10868
- registerAttributeDistortion$LWS(record$LWS, SVGAnimateElement$LWS, 'values', NAMESPACE_DEFAULT$LWS, values$LWS);
12780
+ registerAttributeSetterDistortion$LWS(record$LWS, SVGAnimateElement$LWS, 'values', NAMESPACE_DEFAULT$LWS, values$LWS);
10869
12781
  };
10870
12782
  }
10871
12783
  function initDistortionSVGElementDatasetGetter$LWS({
@@ -10941,10 +12853,10 @@ function initDistortionSVGScriptElementHrefSetter$LWS({
10941
12853
  }
10942
12854
  }) {
10943
12855
  return function distortionSVGScriptElementHrefSetter$LWS(record$LWS) {
10944
- registerAttributeDistortion$LWS(record$LWS, SVGScriptElement$LWS, 'href', NAMESPACE_XLINK$LWS, createScriptDistortion$LWS(record$LWS, 'href'));
10945
- registerAttributeDistortion$LWS(record$LWS, SVGScriptElement$LWS, 'xlink:href', NAMESPACE_XLINK$LWS, createScriptDistortion$LWS(record$LWS, 'xlink:href'));
10946
- registerAttributeDistortion$LWS(record$LWS, SVGScriptElement$LWS, 'href', NAMESPACE_DEFAULT$LWS, createScriptDistortion$LWS(record$LWS, 'href'));
10947
- registerAttributeDistortion$LWS(record$LWS, SVGScriptElement$LWS, 'xlink:href', NAMESPACE_DEFAULT$LWS, createScriptDistortion$LWS(record$LWS, 'xlink:href'));
12856
+ registerAttributeSetterDistortion$LWS(record$LWS, SVGScriptElement$LWS, 'href', NAMESPACE_XLINK$LWS, createScriptDistortion$LWS(record$LWS, 'href'));
12857
+ registerAttributeSetterDistortion$LWS(record$LWS, SVGScriptElement$LWS, 'xlink:href', NAMESPACE_XLINK$LWS, createScriptDistortion$LWS(record$LWS, 'xlink:href'));
12858
+ registerAttributeSetterDistortion$LWS(record$LWS, SVGScriptElement$LWS, 'href', NAMESPACE_DEFAULT$LWS, createScriptDistortion$LWS(record$LWS, 'href'));
12859
+ registerAttributeSetterDistortion$LWS(record$LWS, SVGScriptElement$LWS, 'xlink:href', NAMESPACE_DEFAULT$LWS, createScriptDistortion$LWS(record$LWS, 'xlink:href'));
10948
12860
  };
10949
12861
  }
10950
12862
  function initDistortionSVGSetElementAttributeNameAttribute$LWS({
@@ -10963,7 +12875,7 @@ function initDistortionSVGSetElementAttributeNameAttribute$LWS({
10963
12875
  const originalAttributeValue$LWS = ReflectApply$LWS$1(ElementProtoGetAttribute$LWS, el$LWS, [attrName$LWS]);
10964
12876
  // istanbul ignore else: needs default platform behavior test
10965
12877
  if (originalAttributeValue$LWS) {
10966
- const distortion$LWS = getAttributeDistortion$LWS(record$LWS, el$LWS, attrName$LWS);
12878
+ const distortion$LWS = getAttributeSetterDistortion$LWS(record$LWS, el$LWS, attrName$LWS);
10967
12879
  // istanbul ignore else: needs default platform behavior test
10968
12880
  if (distortion$LWS) {
10969
12881
  ReflectApply$LWS$1(distortion$LWS, el$LWS, [originalAttributeValue$LWS]);
@@ -10977,7 +12889,7 @@ function initDistortionSVGSetElementAttributeNameAttribute$LWS({
10977
12889
  distortAttribute$LWS(this, 'to');
10978
12890
  }
10979
12891
  }
10980
- registerAttributeDistortion$LWS(record$LWS, SVGSetElement$LWS, 'attributeName', NAMESPACE_DEFAULT$LWS, attributeName$LWS);
12892
+ registerAttributeSetterDistortion$LWS(record$LWS, SVGSetElement$LWS, 'attributeName', NAMESPACE_DEFAULT$LWS, attributeName$LWS);
10981
12893
  };
10982
12894
  }
10983
12895
  function initDistortionSVGSetElementToAttribute$LWS({
@@ -10997,7 +12909,7 @@ function initDistortionSVGSetElementToAttribute$LWS({
10997
12909
  ReflectApply$LWS$1(originalSetAttribute$LWS, this, ['to', value$LWS]);
10998
12910
  }
10999
12911
  return function distortionSVGSetElementToAttribute$LWS(record$LWS) {
11000
- registerAttributeDistortion$LWS(record$LWS, SVGSetElement$LWS, 'to', NAMESPACE_DEFAULT$LWS, to$LWS);
12912
+ registerAttributeSetterDistortion$LWS(record$LWS, SVGSetElement$LWS, 'to', NAMESPACE_DEFAULT$LWS, to$LWS);
11001
12913
  };
11002
12914
  }
11003
12915
  function createDistortionHrefAttributeFactoryInitializer$LWS(attributeName$LWS) {
@@ -11017,13 +12929,13 @@ function createDistortionHrefAttributeFactoryInitializer$LWS(attributeName$LWS)
11017
12929
  ReflectApply$LWS$1(originalSetAttributeNS$LWS, this, [NAMESPACE_XLINK$LWS, attributeName$LWS, returnValue$LWS]);
11018
12930
  }
11019
12931
  return function distortionHrefAttributeFactory$LWS(record$LWS) {
11020
- registerAttributeDistortion$LWS(record$LWS, SVGUseElement$LWS, attributeName$LWS, NAMESPACE_XLINK$LWS, xlinkNamespaceDistortion$LWS);
12932
+ registerAttributeSetterDistortion$LWS(record$LWS, SVGUseElement$LWS, attributeName$LWS, NAMESPACE_XLINK$LWS, xlinkNamespaceDistortion$LWS);
11021
12933
  if (attributeName$LWS === 'href') {
11022
12934
  const defaultNamespaceDistortion$LWS = function defaultNamespaceDistortion$LWS(value$LWS) {
11023
12935
  const returnValue$LWS = value$LWS === null || value$LWS === undefined || value$LWS === '' ? /* istanbul ignore next: needs default platform behavior test */value$LWS : sanitizeSvgHref$LWS(value$LWS);
11024
12936
  ReflectApply$LWS$1(originalSetAttribute$LWS, this, [attributeName$LWS, returnValue$LWS]);
11025
12937
  };
11026
- registerAttributeDistortion$LWS(record$LWS, SVGUseElement$LWS, attributeName$LWS, NAMESPACE_DEFAULT$LWS, defaultNamespaceDistortion$LWS);
12938
+ registerAttributeSetterDistortion$LWS(record$LWS, SVGUseElement$LWS, attributeName$LWS, NAMESPACE_DEFAULT$LWS, defaultNamespaceDistortion$LWS);
11027
12939
  }
11028
12940
  };
11029
12941
  };
@@ -11046,7 +12958,18 @@ function initDistortionTrustedTypePolicyFactoryCreatePolicy$LWS({
11046
12958
  return noop$LWS$1;
11047
12959
  }
11048
12960
  const distortionEntry$LWS = [originalCreatePolicy$LWS, function createPolicy$LWS(...args$LWS) {
11049
- const name$LWS = args$LWS.length ? args$LWS[0] : /* istanbul ignore next: needs default platform behavior test */undefined;
12961
+ let name$LWS = args$LWS.length ? args$LWS[0] : /* istanbul ignore next: needs default platform behavior test */undefined;
12962
+ // Coerce the policy name before the equality check. Without this,
12963
+ // a value like `{ toString: () => 'default' }` slips past the
12964
+ // strict equality (object !== string) while the native
12965
+ // createPolicy stringifies it per spec — creating a 'default'
12966
+ // policy LWS thought it had blocked. Substitute the coerced
12967
+ // string into args so the native call sees the same value the
12968
+ // guard inspected.
12969
+ if (isGaterEnabledFeature$LWS('changesSince.264') && args$LWS.length) {
12970
+ name$LWS = toSafeStringValue$LWS(args$LWS[0]);
12971
+ args$LWS[0] = name$LWS;
12972
+ }
11050
12973
  // istanbul ignore else: needs default platform behavior test
11051
12974
  if (name$LWS === 'default') {
11052
12975
  throw new LockerSecurityError$LWS(createTrustedTypesExceptionMessage$LWS(name$LWS));
@@ -11055,7 +12978,7 @@ function initDistortionTrustedTypePolicyFactoryCreatePolicy$LWS({
11055
12978
  try {
11056
12979
  // istanbul ignore next: needs default platform behavior test
11057
12980
  return ReflectApply$LWS$1(originalCreatePolicy$LWS, this, args$LWS);
11058
- } catch (_unused4$LWS) {
12981
+ } catch (_unused5$LWS) {
11059
12982
  // istanbul ignore next: this is tested, but currently cannot be tested in the coverage environment
11060
12983
  consoleWarn$LWS(`${createTrustedTypesExceptionMessage$LWS(name$LWS)} Substituting with Lightning Web Security policy.`);
11061
12984
  }
@@ -11128,7 +13051,7 @@ function initDistortionURLCreateObjectURL$LWS({
11128
13051
  ReflectApply$LWS$1(XhrProtoOpen$LWS, xhr$LWS, ['GET', outURL$LWS, false]);
11129
13052
  try {
11130
13053
  ReflectApply$LWS$1(XhrProtoSend$LWS, xhr$LWS, []);
11131
- } catch (_unused5$LWS) {
13054
+ } catch (_unused6$LWS) {
11132
13055
  throw new LockerSecurityError$LWS(`Unable to verify ${toSafeTemplateStringValue$LWS(blobObject$LWS)} is secure.`);
11133
13056
  }
11134
13057
  const responseText$LWS = ReflectApply$LWS$1(XhrProtoResponseTextGetter$LWS, xhr$LWS, []);
@@ -11545,6 +13468,44 @@ function initDistortionWindowOpen$LWS({
11545
13468
  throw new LockerSecurityError$LWS(`Cannot open disallowed endpoint: ${toSafeTemplateStringValue$LWS(parsedURL$LWS.normalizedURL)}`);
11546
13469
  }
11547
13470
  }
13471
+ // Determine whether the target replaces the current browsing context.
13472
+ const target$LWS = normalizedArgs$LWS.length > 1 ? normalizedArgs$LWS[1] : undefined;
13473
+ const willOpenInSameBrowsingContext$LWS = target$LWS === '_self' || target$LWS === '_parent' || target$LWS === '_top';
13474
+ // W-22297117
13475
+ // Block same-origin window.open() for new browsing contexts and inject
13476
+ // noopener to sever the bidirectional Window reference.
13477
+ //
13478
+ // Threat model: even with noopener (which prevents the *caller* from
13479
+ // getting a child Window handle), a same-origin child page executes
13480
+ // scripts with full system-mode privileges. An attacker can craft a
13481
+ // payload URL (e.g. /resource/...) whose scripts exfiltrate cookies
13482
+ // or session tokens via fetch() without needing a reference back.
13483
+ //
13484
+ // Defence:
13485
+ // 1. Block same-origin URLs for new browsing contexts entirely.
13486
+ // The opened page would run unsandboxed, so navigation to it
13487
+ // must not be allowed from sandboxed code.
13488
+ // 2. Inject "noopener" for any remaining opens (cross-origin, about:
13489
+ // scheme) so the caller never receives a live Window reference.
13490
+ //
13491
+ // Same-browsing-context targets (_self, _parent, _top) are excluded:
13492
+ // they navigate the current context (no new unsandboxed page), and the
13493
+ // existing URL validation (gate 262) already guards them.
13494
+ if (isGaterEnabledFeature$LWS('changesSince.264') && !willOpenInSameBrowsingContext$LWS) {
13495
+ if (isSameOriginURL$LWS(resourceUrl$LWS)) {
13496
+ throw new LockerSecurityError$LWS('Cannot open same-origin URL in a new browsing context.');
13497
+ }
13498
+ // For cross-origin / about: URLs, inject noopener so the caller
13499
+ // receives null and the child has no opener reference.
13500
+ const features$LWS = normalizedArgs$LWS.length > 2 ? normalizedArgs$LWS[2] : undefined;
13501
+ if (typeof features$LWS === 'string' && features$LWS !== '') {
13502
+ if (!isNoopenerPresent$LWS(features$LWS)) {
13503
+ normalizedArgs$LWS[2] = `${features$LWS},noopener`;
13504
+ }
13505
+ } else {
13506
+ normalizedArgs$LWS[2] = 'noopener';
13507
+ }
13508
+ }
11548
13509
  const childWindow$LWS = ReflectApply$LWS$1(originalWindowOpen$LWS, this, normalizedArgs$LWS);
11549
13510
  // istanbul ignore next: behavior will not be tested in collection coverage
11550
13511
  if (!isGaterEnabledFeature$LWS('changesSince.262')) {
@@ -11558,14 +13519,8 @@ function initDistortionWindowOpen$LWS({
11558
13519
  }
11559
13520
  // W-14218118
11560
13521
  // If the target is '_self', '_parent', or '_top', only makes one request
11561
- if (normalizedArgs$LWS.length > 1) {
11562
- const {
11563
- 1: target$LWS
11564
- } = normalizedArgs$LWS;
11565
- const willOpenInSameBrowsingContext$LWS = target$LWS === '_self' || target$LWS === '_parent' || target$LWS === '_top';
11566
- if (willOpenInSameBrowsingContext$LWS) {
11567
- return childWindow$LWS;
11568
- }
13522
+ if (willOpenInSameBrowsingContext$LWS) {
13523
+ return childWindow$LWS;
11569
13524
  }
11570
13525
  // W-13552831
11571
13526
  // If the target is anything else, two requests are made
@@ -11878,22 +13833,32 @@ initDistortionBroadcastChannelPostMessage$LWS,
11878
13833
  initDistortionCSSStyleRuleStyleGetter$LWS,
11879
13834
  // Document
11880
13835
  initDistortionDocumentCreateNodeIterator$LWS, initDistortionDocumentCreateTreeWalker$LWS, initDistortionDocumentDomainSetter$LWS, initDistortionDocumentOnsecuritypolicyviolation$LWS, initDistortionDocumentOpen$LWS,
13836
+ // DOMTokenList
13837
+ initDistortionDOMTokenListAdd$LWS, initDistortionDOMTokenListReplace$LWS, initDistortionDOMTokenListToggle$LWS, initDistortionDOMTokenListValueSetter$LWS,
11881
13838
  // Element
11882
- initDistortionElementAttributesGetter$LWS, initDistortionElementGetInnerHTML$LWS, initDistortionElementInnerHTMLGetter$LWS, initDistortionElementOuterHTMLGetter$LWS, initDistortionElementRemove$LWS, initDistortionElementReplaceChildren$LWS, initDistortionElementReplaceWith$LWS,
13839
+ initDistortionElementAttributesGetter$LWS, initDistortionElementGetInnerHTML$LWS, initDistortionElementInnerHTMLGetter$LWS, initDistortionElementOuterHTMLGetter$LWS, initDistortionElementRemove$LWS, initDistortionElementRemoveAttribute$LWS, initDistortionElementRemoveAttributeNS$LWS, initDistortionElementRemoveAttributeNode$LWS, initDistortionElementReplaceChildren$LWS, initDistortionElementReplaceWith$LWS,
11883
13840
  // Function
11884
- initDistortionFunction$LWS,
13841
+ initDistortionFunction$LWS, initDistortionFunctionApply$LWS, initDistortionFunctionBind$LWS, initDistortionFunctionCall$LWS,
11885
13842
  // History
11886
13843
  initDistortionHistoryPushState$LWS, initDistortionHistoryReplaceState$LWS,
11887
13844
  // HTMLElement
11888
13845
  initDistortionHTMLElementDatasetGetter$LWS, initDistortionHTMLElementInnerTextGetter$LWS, initDistortionHTMLElementInnerTextSetter$LWS, initDistortionHTMLElementOuterTextSetter$LWS, initDistortionHTMLElementStyleGetter$LWS,
11889
13846
  // HTMLIFrameElement
11890
- initDistortionIFrameElementContentDocumentGetter$LWS, initDistortionIFrameElementContentWindowGetter$LWS, initDistortionHTMLIFrameElementSandboxGetter$LWS, initDistortionHTMLIFrameElementSandboxSetter$LWS, initDistortionHTMLIFrameElementSrcSetter$LWS,
13847
+ initDistortionIFrameElementContentDocumentGetter$LWS, initDistortionIFrameElementContentWindowGetter$LWS, initDistortionHTMLIFrameElementSandboxGetter$LWS, initDistortionHTMLIFrameElementSandboxSetter$LWS, initDistortionHTMLIFrameElementSrcGetter$LWS, initDistortionHTMLIFrameElementSrcSetter$LWS,
13848
+ // HTMLImageElement
13849
+ initDistortionHTMLImageElementSrcSetter$LWS, initDistortionHTMLImageElementSrcsetSetter$LWS,
11891
13850
  // HTMLLinkElement
11892
- initDistortionHTMLLinkElementRelSetter$LWS, initDistortionHTMLLinkElementRelListSetter$LWS,
13851
+ initDistortionHTMLLinkElementHrefSetter$LWS, initDistortionHTMLLinkElementRelSetter$LWS, initDistortionHTMLLinkElementRelListSetter$LWS,
13852
+ // HTMLMediaElement
13853
+ initDistortionHTMLMediaElementSrcSetter$LWS,
11893
13854
  // HTMLMetaElement
11894
13855
  initDistortionHTMLMetaElementContentGetter$LWS,
11895
13856
  // HTMLObjectElement
11896
- initDistortionHTMLObjectElementDataSetter$LWS,
13857
+ initDistortionHTMLObjectElementContentDocumentGetter$LWS, initDistortionHTMLObjectElementContentWindowGetter$LWS, initDistortionHTMLObjectElementDataSetter$LWS, initDistortionHTMLObjectElementTypeSetter$LWS,
13858
+ // HTMLSourceElement
13859
+ initDistortionHTMLSourceElementSrcSetter$LWS, initDistortionHTMLSourceElementSrcsetSetter$LWS,
13860
+ // HTMLTrackElement
13861
+ initDistortionHTMLTrackElementSrcSetter$LWS,
11897
13862
  // HTMLScriptElement
11898
13863
  initDistortionHTMLScriptElementInnerTextGetter$LWS, initDistortionHTMLScriptElementInnerTextSetter$LWS, initDistortionHTMLScriptElementSrcGetter$LWS, initDistortionHTMLScriptElementTextContentGetter$LWS, initDistortionHTMLScriptElementTextContentSetter$LWS, initDistortionHTMLScriptElementTextGetter$LWS, initDistortionHTMLScriptElementTextSetter$LWS,
11899
13864
  // IDBObjectStore
@@ -11915,7 +13880,7 @@ initDistortionNavigatorSendBeacon$LWS, initDistortionNavigatorServiceWorkerGette
11915
13880
  // Observable
11916
13881
  initDistortionObservableForEach$LWS, initDistortionObservableSubscribe$LWS,
11917
13882
  // Node
11918
- initDistortionNodeRemoveChild$LWS, initDistortionNodeReplaceChild$LWS,
13883
+ initDistortionNodeGetRootNode$LWS, initDistortionNodeParentElementGetter$LWS, initDistortionNodeParentNodeGetter$LWS, initDistortionNodeRemoveChild$LWS, initDistortionNodeReplaceChild$LWS,
11919
13884
  // Performance
11920
13885
  initDistortionPerformanceMark$LWS, initDistortionPerformanceMeasure$LWS,
11921
13886
  // PerformanceMark
@@ -11926,6 +13891,8 @@ initDistortionPromiseAll$LWS, initDistortionPromiseAllSettled$LWS, initDistortio
11926
13891
  initDistortionNotificationCtor$LWS,
11927
13892
  // Range
11928
13893
  initDistortionRangeCloneContents$LWS, initDistortionRangeCloneRange$LWS, initDistortionRangeDeleteContents$LWS, initDistortionRangeExtractContents$LWS, initDistortionRangeGetBoundingClientRect$LWS, initDistortionRangeInsertNode$LWS, initDistortionRangeSelectNode$LWS, initDistortionRangeSelectNodeContents$LWS, initDistortionRangeSetEnd$LWS, initDistortionRangeSetEndAfter$LWS, initDistortionRangeSetEndBefore$LWS, initDistortionRangeSetStart$LWS, initDistortionRangeSetStartAfter$LWS, initDistortionRangeSetStartBefore$LWS, initDistortionRangeSurroundContents$LWS, initDistortionRangeToString$LWS,
13894
+ // Reflect
13895
+ initDistortionReflectApply$LWS, initDistortionReflectConstruct$LWS,
11929
13896
  // Selection
11930
13897
  initDistortionSelectionAnchorNodeGetter$LWS, initDistortionSelectionCollapse$LWS, initDistortionSelectionExtend$LWS, initDistortionSelectionFocusNodeGetter$LWS, initDistortionSelectionSelectAllChildren$LWS, initDistortionSelectionSetBaseAndExtent$LWS, initDistortionSelectionSetPosition$LWS, initDistortionSelectionToString$LWS,
11931
13898
  // ServiceWorkerContainer
@@ -11954,9 +13921,11 @@ initDistortionWorkerCtor$LWS, initDistortionWorkerProto$LWS,
11954
13921
  initDistortionXMLHttpRequestOpen$LWS];
11955
13922
  const internalKeyedDistortionFactoryInitializers$LWS = [
11956
13923
  // Attr
11957
- initDistortionAttrValueSetter$LWS,
13924
+ initDistortionAttrValueGetter$LWS, initDistortionAttrValueSetter$LWS,
11958
13925
  // Aura
11959
13926
  initDistortionAuraUtilGlobalEval$LWS,
13927
+ // BroadcastChannel
13928
+ initDistortionBroadcastChannelCtor$LWS, initDistortionBroadcastChannelNameGetter$LWS,
11960
13929
  // CacheStorage
11961
13930
  initDistortionCacheStorageDelete$LWS, initDistortionCacheStorageHas$LWS, initDistortionCacheStorageKeys$LWS, initDistortionCacheStorageMatch$LWS, initDistortionCacheStorageOpen$LWS,
11962
13931
  // CookieStore
@@ -11964,7 +13933,7 @@ initDistortionCookieStoreDelete$LWS, initDistortionCookieStoreGet$LWS, initDisto
11964
13933
  // CustomElementRegistry
11965
13934
  initDistortionCustomElementRegistryDefine$LWS, initDistortionCustomElementRegistryGet$LWS, initDistortionCustomElementRegistryUpgrade$LWS, initDistortionCustomElementRegistryWhenDefined$LWS,
11966
13935
  // Document
11967
- initDistortionDocumentCookieGetter$LWS, initDistortionDocumentCookieSetter$LWS, initDistortionDocumentCreateElement$LWS, initDistortionDocumentCreateElementNS$LWS, initDistortionDocumentExecCommand$LWS, initDistortionDocumentReplaceChildren$LWS,
13936
+ initDistortionDocumentCookieGetter$LWS, initDistortionDocumentCookieSetter$LWS, initDistortionDocumentCreateElement$LWS, initDistortionDocumentCreateElementNS$LWS, initDistortionDocumentExecCommand$LWS, initDistortionDocumentAdoptNode$LWS, initDistortionDocumentImportNode$LWS, initDistortionDocumentReplaceChildren$LWS,
11968
13937
  // DOMParser
11969
13938
  initDistortionDOMParserParseFromString$LWS,
11970
13939
  // Element
@@ -11974,9 +13943,9 @@ initDistortionEval$LWS,
11974
13943
  // Event
11975
13944
  initDistortionEventComposedPath$LWS, initDistortionEventPathGetter$LWS,
11976
13945
  // EventTarget
11977
- initDistortionEventTargetAddEventListener$LWS,
13946
+ initDistortionEventTargetAddEventListener$LWS, initDistortionEventTargetDispatchEvent$LWS,
11978
13947
  // HTMLAnchorElement
11979
- initDistortionHTMLAnchorElementHrefSetter$LWS,
13948
+ initDistortionHTMLAnchorElementHrefSetter$LWS, initDistortionHTMLAnchorElementProtocolSetter$LWS,
11980
13949
  // HTMLBaseElement
11981
13950
  initDistortionHTMLBaseElementHrefSetter$LWS,
11982
13951
  // HTMLBodyElement
@@ -11998,7 +13967,7 @@ initDistortionIDBFactoryDatabases$LWS, initDistortionIDBFactoryDeleteDatabase$LW
11998
13967
  // MathMLElement
11999
13968
  initDistortionMathMLElementOnsecuritypolicyviolation$LWS,
12000
13969
  // NamedNodeMap
12001
- initDistortionNamedNodeMapSetNamedItem$LWS, initDistortionNamedNodeMapSetNamedItemNS$LWS,
13970
+ initDistortionNamedNodeMapGetNamedItem$LWS, initDistortionNamedNodeMapGetNamedItemNS$LWS, initDistortionNamedNodeMapRemoveNamedItem$LWS, initDistortionNamedNodeMapRemoveNamedItemNS$LWS, initDistortionNamedNodeMapSetNamedItem$LWS, initDistortionNamedNodeMapSetNamedItemNS$LWS,
12002
13971
  // Node
12003
13972
  initDistortionNodeValueSetter$LWS, initDistortionNodeTextContentGetter$LWS, initDistortionNodeTextContentSetter$LWS,
12004
13973
  // Range
@@ -12028,14 +13997,15 @@ initDistortionElementAfter$LWS, initDistortionElementAppend$LWS, initDistortionE
12028
13997
  // initDistortionNodeAppendChild,
12029
13998
  initDistortionNodeInsertBefore$LWS]);
12030
13999
  const externalKeyedDistortionFactoryInitializers$LWS = internalKeyedDistortionFactoryInitializers$LWS;
12031
- const distortionFactoryInitializerToggleSwitches$LWS = toSafeMap$LWS$1(new MapCtor$LWS$1([[initDistortionCacheStorageDelete$LWS, 'caches'], [initDistortionCacheStorageHas$LWS, 'caches'], [initDistortionCacheStorageKeys$LWS, 'caches'], [initDistortionCacheStorageMatch$LWS, 'caches'], [initDistortionCacheStorageOpen$LWS, 'caches'], [initDistortionCookieStoreDelete$LWS, 'cookieStore'], [initDistortionCookieStoreGet$LWS, 'cookieStore'], [initDistortionCookieStoreGetAll$LWS, 'cookieStore'], [initDistortionCookieStoreOnChange$LWS, 'cookieStore'], [initDistortionCookieStoreSet$LWS, 'cookieStore'], [initDistortionCSSStyleRuleStyleGetter$LWS, 'style'], [initDistortionCustomElementRegistryDefine$LWS, 'customElements'], [initDistortionCustomElementRegistryGet$LWS, 'customElements'], [initDistortionCustomElementRegistryUpgrade$LWS, 'customElements'], [initDistortionCustomElementRegistryWhenDefined$LWS, 'customElements'], [initDistortionDocumentCookieGetter$LWS, 'documentCookie'], [initDistortionDocumentCookieSetter$LWS, 'documentCookie'], [initDistortionDocumentDomainSetter$LWS, 'documentDomain'], [initDistortionDocumentExecCommand$LWS, 'documentExecCommand'], [initDistortionDOMParserParseFromString$LWS, 'domParserParseFromString'], [initDistortionElementAfter$LWS, 'element'], [initDistortionElementAppend$LWS, 'element'], [initDistortionElementAttributesGetter$LWS, 'attributes'], [initDistortionElementBefore$LWS, 'element'], [initDistortionElementGetInnerHTML$LWS, 'innerHTML'], [initDistortionElementInnerHTMLSetter$LWS, 'innerHTML'], [initDistortionElementInsertAdjacentElement$LWS, 'element'], [initDistortionElementInsertAdjacentHTML$LWS, 'element'], [initDistortionElementOuterHTMLSetter$LWS, 'element'], [initDistortionElementPrepend$LWS, 'element'], [initDistortionElementRemove$LWS, 'element'], [initDistortionElementReplaceChildren$LWS, 'element'], [initDistortionElementReplaceWith$LWS, 'element'], [initDistortionElementGetAttribute$LWS, 'attributes'], [initDistortionElementGetAttributeNode$LWS, 'attributes'], [initDistortionElementGetAttributeNodeNS$LWS, 'attributes'], [initDistortionElementGetAttributeNS$LWS, 'attributes'], [initDistortionElementSetAttribute$LWS, 'attributes'], [initDistortionElementSetAttributeNode$LWS, 'attributes'], [initDistortionElementSetAttributeNodeNS$LWS, 'attributes'], [initDistortionElementSetAttributeNS$LWS, 'attributes'], [initDistortionElementSetHTML$LWS, 'element'], [initDistortionElementToggleAttribute$LWS, 'attributes'], [initDistortionHTMLButtonElementFormActionSetter$LWS, 'form'], [initDistortionHTMLFormElementActionSetter$LWS, 'form'], [initDistortionHTMLInputElementFormActionSetter$LWS, 'form'], [initDistortionHistoryPushState$LWS, 'history'], [initDistortionHistoryReplaceState$LWS, 'history'], [initDistortionHTMLElementDatasetGetter$LWS, 'dataset'], [initDistortionHTMLElementStyleGetter$LWS, 'style'], [initDistortionHTMLScriptElementInnerTextGetter$LWS, 'script'], [initDistortionHTMLScriptElementInnerTextSetter$LWS, 'script'], [initDistortionHTMLScriptElementSrcGetter$LWS, 'script'], [initDistortionHTMLScriptElementSrcSetter$LWS, 'script'], [initDistortionHTMLScriptElementTextGetter$LWS, 'script'], [initDistortionHTMLScriptElementTextSetter$LWS, 'script'], [initDistortionIDBFactoryDatabases$LWS, 'indexedDB'], [initDistortionIDBFactoryDeleteDatabase$LWS, 'indexedDB'], [initDistortionIDBFactoryOpen$LWS, 'indexedDB'], [initDistortionIDBObjectStoreAdd$LWS, 'indexedDB'], [initDistortionIDBObjectStorePut$LWS, 'indexedDB'], [initDistortionLocalStorage$LWS, 'storage'], [initDistortionMessagePortPostMessage$LWS, 'postMessage'], [initDistortionIntersectionObserverObserve$LWS, 'observers'], [initDistortionMutationObserverObserve$LWS, 'mutationObserver'], [initDistortionPerformanceObserverObserve$LWS, 'observers'], [initDistortionResizeObserverObserve$LWS, 'observers'], [initDistortionNamedNodeMapSetNamedItem$LWS, 'attributes'], [initDistortionNamedNodeMapSetNamedItemNS$LWS, 'attributes'], [initDistortionNavigatorSendBeacon$LWS, 'navigatorSendBeacon'], [initDistortionObservableForEach$LWS, 'observable'], [initDistortionObservableSubscribe$LWS, 'observable'], [initDistortionNodeInsertBefore$LWS, 'node'], [initDistortionNodeRemoveChild$LWS, 'node'], [initDistortionNodeReplaceChild$LWS, 'node'], [initDistortionNodeTextContentGetter$LWS, 'node'], [initDistortionNodeTextContentSetter$LWS, 'node'], [initDistortionNodeValueSetter$LWS, 'node'], [initDistortionNotificationCtor$LWS, 'notification'], [initDistortionPerformanceMark$LWS, 'performance'], [initDistortionPerformanceMarkCtor$LWS, 'performance'], [initDistortionPerformanceMeasure$LWS, 'performance'], [initDistortionRangeCloneContents$LWS, 'range'], [initDistortionRangeCloneRange$LWS, 'range'], [initDistortionRangeCreateContextualFragment$LWS, 'range'], [initDistortionRangeDeleteContents$LWS, 'range'], [initDistortionRangeExtractContents$LWS, 'range'], [initDistortionRangeGetBoundingClientRect$LWS, 'range'], [initDistortionRangeInsertNode$LWS, 'range'], [initDistortionRangeSelectNode$LWS, 'range'], [initDistortionRangeSelectNodeContents$LWS, 'range'], [initDistortionRangeSetEnd$LWS, 'range'], [initDistortionRangeSetEndAfter$LWS, 'range'], [initDistortionRangeSetEndBefore$LWS, 'range'], [initDistortionRangeSetStart$LWS, 'range'], [initDistortionRangeSetStartAfter$LWS, 'range'], [initDistortionRangeSetStartBefore$LWS, 'range'], [initDistortionRangeSurroundContents$LWS, 'range'], [initDistortionRangeToString$LWS, 'range'], [initDistortionSelectionAnchorNodeGetter$LWS, 'selection'], [initDistortionSelectionCollapse$LWS, 'selection'], [initDistortionSelectionExtend$LWS, 'selection'], [initDistortionSelectionFocusNodeGetter$LWS, 'selection'], [initDistortionSelectionSelectAllChildren$LWS, 'selection'], [initDistortionSelectionSetBaseAndExtent$LWS, 'selection'], [initDistortionSelectionSetPosition$LWS, 'selection'], [initDistortionSelectionToString$LWS, 'selection'], [initDistortionSessionStorage$LWS, 'storage'], [initDistortionShadowRootInnerHTMLSetter$LWS, 'innerHTML'], [initDistortionStorage$LWS, 'storage'], [initDistortionStorageClear$LWS, 'storage'], [initDistortionStorageGetItem$LWS, 'storage'], [initDistortionStorageKey$LWS, 'storage'], [initDistortionStorageLength$LWS, 'storage'], [initDistortionStorageRemoveItem$LWS, 'storage'], [initDistortionStorageSetItem$LWS, 'storage'], [initDistortionSVGElementDatasetGetter$LWS, 'dataset'], [initDistortionSVGElementStyleGetter$LWS, 'style'], [initDistortionSVGAnimatedStringBaseValSetter$LWS, 'script'], [initDistortionSVGScriptElementHrefGetter$LWS, 'script'], [initDistortionSVGScriptElementHrefSetter$LWS, 'script'], [initDistortionWindowFetch$LWS, 'windowFetch'], [initDistortionWindowFetchLater$LWS, 'windowFetchLater'], [initDistortionWindowFramesGetter$LWS, 'windowFrames'], [initDistortionWindowGetComputedStyle$LWS, 'style'], [initDistortionWindowLengthGetter$LWS, 'windowFrames'], [initDistortionWindowNameGetter$LWS, 'windowName'], [initDistortionWindowNameSetter$LWS, 'windowName'], [initDistortionWindowPostMessage$LWS, 'postMessage'], [initDistortionWindowSetInterval$LWS, 'setInterval'], [initDistortionWindowSetTimeout$LWS, 'setTimeout'], [initDistortionXMLHttpRequestResponseGetter$LWS, 'xhr'], [initDistortionXMLHttpRequestResponseXMLGetter$LWS, 'xhr']]));
14000
+ const distortionFactoryInitializerToggleSwitches$LWS = toSafeMap$LWS$1(new MapCtor$LWS$1([[initDistortionBroadcastChannelCtor$LWS, 'broadcastChannel'], [initDistortionBroadcastChannelNameGetter$LWS, 'broadcastChannel'], [initDistortionCacheStorageDelete$LWS, 'caches'], [initDistortionCacheStorageHas$LWS, 'caches'], [initDistortionCacheStorageKeys$LWS, 'caches'], [initDistortionCacheStorageMatch$LWS, 'caches'], [initDistortionCacheStorageOpen$LWS, 'caches'], [initDistortionCookieStoreDelete$LWS, 'cookieStore'], [initDistortionCookieStoreGet$LWS, 'cookieStore'], [initDistortionCookieStoreGetAll$LWS, 'cookieStore'], [initDistortionCookieStoreOnChange$LWS, 'cookieStore'], [initDistortionCookieStoreSet$LWS, 'cookieStore'], [initDistortionCSSStyleRuleStyleGetter$LWS, 'style'], [initDistortionCustomElementRegistryDefine$LWS, 'customElements'], [initDistortionCustomElementRegistryGet$LWS, 'customElements'], [initDistortionCustomElementRegistryUpgrade$LWS, 'customElements'], [initDistortionCustomElementRegistryWhenDefined$LWS, 'customElements'], [initDistortionDocumentCookieGetter$LWS, 'documentCookie'], [initDistortionDocumentCookieSetter$LWS, 'documentCookie'], [initDistortionDocumentDomainSetter$LWS, 'documentDomain'], [initDistortionDocumentExecCommand$LWS, 'documentExecCommand'], [initDistortionDOMParserParseFromString$LWS, 'domParserParseFromString'], [initDistortionDOMTokenListAdd$LWS, 'domTokenList'], [initDistortionDOMTokenListReplace$LWS, 'domTokenList'], [initDistortionDOMTokenListToggle$LWS, 'domTokenList'], [initDistortionDOMTokenListValueSetter$LWS, 'domTokenList'], [initDistortionElementAfter$LWS, 'element'], [initDistortionElementAppend$LWS, 'element'], [initDistortionElementAttributesGetter$LWS, 'attributes'], [initDistortionElementBefore$LWS, 'element'], [initDistortionElementGetInnerHTML$LWS, 'innerHTML'], [initDistortionElementInnerHTMLSetter$LWS, 'innerHTML'], [initDistortionElementInsertAdjacentElement$LWS, 'element'], [initDistortionElementInsertAdjacentHTML$LWS, 'element'], [initDistortionElementOuterHTMLSetter$LWS, 'element'], [initDistortionElementPrepend$LWS, 'element'], [initDistortionElementRemove$LWS, 'element'], [initDistortionElementReplaceChildren$LWS, 'element'], [initDistortionElementReplaceWith$LWS, 'element'], [initDistortionElementGetAttribute$LWS, 'attributes'], [initDistortionElementGetAttributeNode$LWS, 'attributes'], [initDistortionElementGetAttributeNodeNS$LWS, 'attributes'], [initDistortionElementGetAttributeNS$LWS, 'attributes'], [initDistortionElementSetAttribute$LWS, 'attributes'], [initDistortionElementSetAttributeNode$LWS, 'attributes'], [initDistortionElementSetAttributeNodeNS$LWS, 'attributes'], [initDistortionElementSetAttributeNS$LWS, 'attributes'], [initDistortionElementRemoveAttribute$LWS, 'attributes'], [initDistortionElementRemoveAttributeNS$LWS, 'attributes'], [initDistortionElementRemoveAttributeNode$LWS, 'attributes'], [initDistortionElementSetHTML$LWS, 'element'], [initDistortionElementToggleAttribute$LWS, 'attributes'], [initDistortionHTMLButtonElementFormActionSetter$LWS, 'form'], [initDistortionHTMLFormElementActionSetter$LWS, 'form'], [initDistortionHTMLInputElementFormActionSetter$LWS, 'form'], [initDistortionHistoryPushState$LWS, 'history'], [initDistortionHistoryReplaceState$LWS, 'history'], [initDistortionHTMLElementDatasetGetter$LWS, 'dataset'], [initDistortionHTMLElementStyleGetter$LWS, 'style'], [initDistortionHTMLImageElementSrcSetter$LWS, 'networkSrc'], [initDistortionHTMLImageElementSrcsetSetter$LWS, 'networkSrc'], [initDistortionHTMLLinkElementHrefSetter$LWS, 'networkSrc'], [initDistortionHTMLMediaElementSrcSetter$LWS, 'networkSrc'], [initDistortionHTMLSourceElementSrcSetter$LWS, 'networkSrc'], [initDistortionHTMLSourceElementSrcsetSetter$LWS, 'networkSrc'], [initDistortionHTMLTrackElementSrcSetter$LWS, 'networkSrc'], [initDistortionHTMLScriptElementInnerTextGetter$LWS, 'script'], [initDistortionHTMLScriptElementInnerTextSetter$LWS, 'script'], [initDistortionHTMLScriptElementSrcGetter$LWS, 'script'], [initDistortionHTMLScriptElementSrcSetter$LWS, 'script'], [initDistortionHTMLScriptElementTextGetter$LWS, 'script'], [initDistortionHTMLScriptElementTextSetter$LWS, 'script'], [initDistortionIDBFactoryDatabases$LWS, 'indexedDB'], [initDistortionIDBFactoryDeleteDatabase$LWS, 'indexedDB'], [initDistortionIDBFactoryOpen$LWS, 'indexedDB'], [initDistortionIDBObjectStoreAdd$LWS, 'indexedDB'], [initDistortionIDBObjectStorePut$LWS, 'indexedDB'], [initDistortionLocalStorage$LWS, 'storage'], [initDistortionMessagePortPostMessage$LWS, 'postMessage'], [initDistortionIntersectionObserverObserve$LWS, 'observers'], [initDistortionMutationObserverObserve$LWS, 'mutationObserver'], [initDistortionPerformanceObserverObserve$LWS, 'observers'], [initDistortionResizeObserverObserve$LWS, 'observers'], [initDistortionAttrValueGetter$LWS, 'attributes'], [initDistortionAttrValueSetter$LWS, 'attributes'], [initDistortionNamedNodeMapGetNamedItem$LWS, 'attributes'], [initDistortionNamedNodeMapGetNamedItemNS$LWS, 'attributes'], [initDistortionNamedNodeMapRemoveNamedItem$LWS, 'attributes'], [initDistortionNamedNodeMapRemoveNamedItemNS$LWS, 'attributes'], [initDistortionNamedNodeMapSetNamedItem$LWS, 'attributes'], [initDistortionNamedNodeMapSetNamedItemNS$LWS, 'attributes'], [initDistortionNavigatorSendBeacon$LWS, 'navigatorSendBeacon'], [initDistortionObservableForEach$LWS, 'observable'], [initDistortionObservableSubscribe$LWS, 'observable'], [initDistortionNodeGetRootNode$LWS, 'node'], [initDistortionNodeInsertBefore$LWS, 'node'], [initDistortionNodeParentElementGetter$LWS, 'node'], [initDistortionNodeParentNodeGetter$LWS, 'node'], [initDistortionNodeRemoveChild$LWS, 'node'], [initDistortionNodeReplaceChild$LWS, 'node'], [initDistortionNodeTextContentGetter$LWS, 'node'], [initDistortionNodeTextContentSetter$LWS, 'node'], [initDistortionNodeValueSetter$LWS, 'node'], [initDistortionNotificationCtor$LWS, 'notification'], [initDistortionPerformanceMark$LWS, 'performance'], [initDistortionPerformanceMarkCtor$LWS, 'performance'], [initDistortionPerformanceMeasure$LWS, 'performance'], [initDistortionRangeCloneContents$LWS, 'range'], [initDistortionRangeCloneRange$LWS, 'range'], [initDistortionRangeCreateContextualFragment$LWS, 'range'], [initDistortionRangeDeleteContents$LWS, 'range'], [initDistortionRangeExtractContents$LWS, 'range'], [initDistortionRangeGetBoundingClientRect$LWS, 'range'], [initDistortionRangeInsertNode$LWS, 'range'], [initDistortionRangeSelectNode$LWS, 'range'], [initDistortionRangeSelectNodeContents$LWS, 'range'], [initDistortionRangeSetEnd$LWS, 'range'], [initDistortionRangeSetEndAfter$LWS, 'range'], [initDistortionRangeSetEndBefore$LWS, 'range'], [initDistortionRangeSetStart$LWS, 'range'], [initDistortionRangeSetStartAfter$LWS, 'range'], [initDistortionRangeSetStartBefore$LWS, 'range'], [initDistortionRangeSurroundContents$LWS, 'range'], [initDistortionRangeToString$LWS, 'range'], [initDistortionSelectionAnchorNodeGetter$LWS, 'selection'], [initDistortionSelectionCollapse$LWS, 'selection'], [initDistortionSelectionExtend$LWS, 'selection'], [initDistortionSelectionFocusNodeGetter$LWS, 'selection'], [initDistortionSelectionSelectAllChildren$LWS, 'selection'], [initDistortionSelectionSetBaseAndExtent$LWS, 'selection'], [initDistortionSelectionSetPosition$LWS, 'selection'], [initDistortionSelectionToString$LWS, 'selection'], [initDistortionSessionStorage$LWS, 'storage'], [initDistortionShadowRootInnerHTMLSetter$LWS, 'innerHTML'], [initDistortionStorage$LWS, 'storage'], [initDistortionStorageClear$LWS, 'storage'], [initDistortionStorageGetItem$LWS, 'storage'], [initDistortionStorageKey$LWS, 'storage'], [initDistortionStorageLength$LWS, 'storage'], [initDistortionStorageRemoveItem$LWS, 'storage'], [initDistortionStorageSetItem$LWS, 'storage'], [initDistortionSVGElementDatasetGetter$LWS, 'dataset'], [initDistortionSVGElementStyleGetter$LWS, 'style'], [initDistortionSVGAnimatedStringBaseValSetter$LWS, 'script'], [initDistortionSVGScriptElementHrefGetter$LWS, 'script'], [initDistortionSVGScriptElementHrefSetter$LWS, 'script'], [initDistortionWindowFetch$LWS, 'windowFetch'], [initDistortionWindowFetchLater$LWS, 'windowFetchLater'], [initDistortionWindowFramesGetter$LWS, 'windowFrames'], [initDistortionWindowGetComputedStyle$LWS, 'style'], [initDistortionWindowLengthGetter$LWS, 'windowFrames'], [initDistortionWindowNameGetter$LWS, 'windowName'], [initDistortionWindowNameSetter$LWS, 'windowName'], [initDistortionWindowPostMessage$LWS, 'postMessage'], [initDistortionWindowSetInterval$LWS, 'setInterval'], [initDistortionWindowSetTimeout$LWS, 'setTimeout'], [initDistortionXMLHttpRequestResponseGetter$LWS, 'xhr'], [initDistortionXMLHttpRequestResponseXMLGetter$LWS, 'xhr']]));
12032
14001
  const DocumentBlockedProperties$LWS = ['parseHTMLUnsafe'];
12033
14002
  const DocumentProtoBlockedProperties$LWS = ['createProcessingInstruction', 'exitFullscreen', 'fullscreen', 'fullscreenElement', 'fullscreenEnabled', 'mozCancelFullScreen', 'mozFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'onfullscreenchange', 'onfullscreenerror', 'onmozfullscreenchange', 'onmozfullscreenerror', 'onrejectionhandled', 'onunhandledrejection', 'parseHTMLUnsafe', 'releaseCapture', 'releaseEvents', 'requestStorageAccess', 'webkitFullScreenKeyboardInputAllowed', 'write', 'writeln'];
12034
14003
  const ElementProtoBlockedProperties$LWS = ['mozRequestFullScreen', 'onfullscreenchange', 'onfullscreenerror', 'requestFullscreen', 'webkitRequestFullScreen', 'webkitRequestFullscreen'];
12035
14004
  const EventProtoBlockedProperties$LWS = ['originalTarget', 'explicitOriginalTarget'];
12036
14005
  const HTMLElementBlockedAttributes$LWS = ['nonce'];
12037
14006
  const HTMLElementProtoBlockedProperties$LWS = ['nonce', 'onrejectionhandled', 'onunhandledrejection'];
12038
- const HTMLEmbedElementProtoBlockedProperties$LWS = ['getSVGDocument'];
14007
+ const HTMLEmbedElementBlockedAttributes$LWS = ['src'];
14008
+ const HTMLEmbedElementProtoBlockedProperties$LWS = ['getSVGDocument', 'src'];
12039
14009
 
12040
14010
  // https://www.w3schools.com/tags/tag_iframe.asp
12041
14011
  const HTMLIFrameElementBlockedAttributes$LWS = ['srcdoc'];
@@ -12048,7 +14018,7 @@ const SVGElementProtoBlockedProperties$LWS = ['nonce'];
12048
14018
  const UIEventProtoBlockedProperties$LWS = ['rangeParent'];
12049
14019
  const WindowBlockedProperties$LWS = ['find', 'requestFileSystem', 'webkitRequestFileSystem'];
12050
14020
  const XSLTProcessorProtoBlockedProperties$LWS = ['transformToDocument', 'transformToFragment'];
12051
- /*! version: 0.28.1 */
14021
+ /*! version: 0.28.3 */
12052
14022
 
12053
14023
  /*!
12054
14024
  * Copyright (C) 2021 salesforce.com, inc.
@@ -12057,7 +14027,7 @@ let pdpSchema$LWS;
12057
14027
  function getPdpSchema$LWS() {
12058
14028
  return pdpSchema$LWS;
12059
14029
  }
12060
- /*! version: 0.28.1 */
14030
+ /*! version: 0.28.3 */
12061
14031
 
12062
14032
  /*!
12063
14033
  * Copyright (C) 2019 salesforce.com, inc.
@@ -12317,10 +14287,21 @@ function getDistortionFactories$LWS(record$LWS) {
12317
14287
  const initializers$LWS = type$LWS === 1 /* SandboxType.Internal */ ?
12318
14288
  // instanbul ignore next: coverage is collected on the external sandbox test run
12319
14289
  ArrayConcat$LWS(internalDistortionFactoryInitializers$LWS, internalKeyedDistortionFactoryInitializers$LWS) : ArrayConcat$LWS(externalDistortionFactoryInitializers$LWS, externalKeyedDistortionFactoryInitializers$LWS);
12320
- addBlockedAttributeDistortionFactoryInitializers$LWS(HTMLElement$LWS, 'HTMLElement', HTMLElementBlockedAttributes$LWS, initializers$LWS);
12321
- addBlockedAttributeDistortionFactoryInitializers$LWS(HTMLIFrameElement$LWS, 'HTMLIFrameElement', HTMLIFrameElementBlockedAttributes$LWS, initializers$LWS);
12322
- addBlockedAttributeDistortionFactoryInitializers$LWS(HTMLScriptElement$LWS, 'HTMLScriptElement', HTMLScriptElementBlockedAttributes$LWS, initializers$LWS);
12323
- addBlockedAttributeDistortionFactoryInitializers$LWS(SVGElement$LWS, 'SVGElement', SVGElementBlockedAttributes$LWS, initializers$LWS);
14290
+ addBlockedAttributeSetterDistortionFactoryInitializers$LWS(HTMLElement$LWS, 'HTMLElement', HTMLElementBlockedAttributes$LWS, initializers$LWS);
14291
+ addBlockedAttributeSetterDistortionFactoryInitializers$LWS(HTMLEmbedElement, 'HTMLEmbedElement', HTMLEmbedElementBlockedAttributes$LWS, initializers$LWS);
14292
+ addBlockedAttributeSetterDistortionFactoryInitializers$LWS(HTMLIFrameElement$LWS, 'HTMLIFrameElement', HTMLIFrameElementBlockedAttributes$LWS, initializers$LWS);
14293
+ addBlockedAttributeSetterDistortionFactoryInitializers$LWS(HTMLScriptElement$LWS, 'HTMLScriptElement', HTMLScriptElementBlockedAttributes$LWS, initializers$LWS);
14294
+ addBlockedAttributeSetterDistortionFactoryInitializers$LWS(SVGElement$LWS, 'SVGElement', SVGElementBlockedAttributes$LWS, initializers$LWS);
14295
+ // Read-side block list: only the subset of write-blocked attributes that
14296
+ // ALSO must not be readable. Today this is `nonce` only; attributes like
14297
+ // `srcdoc` (HTMLIFrameElement) and `src` (HTMLEmbedElement) are
14298
+ // write-blocked but legitimately readable, so they must NOT be added
14299
+ // here. Closes previously-leaking surfaces (NamedNodeMap subscript,
14300
+ // getNamedItem(NS), Attr.value) for the read-blocked subset.
14301
+ const READ_BLOCKED_NONCE$LWS = ['nonce'];
14302
+ addBlockedAttributeGetterDistortionFactoryInitializers$LWS(HTMLElement$LWS, READ_BLOCKED_NONCE$LWS, initializers$LWS);
14303
+ addBlockedAttributeGetterDistortionFactoryInitializers$LWS(HTMLScriptElement$LWS, READ_BLOCKED_NONCE$LWS, initializers$LWS);
14304
+ addBlockedAttributeGetterDistortionFactoryInitializers$LWS(SVGElement$LWS, READ_BLOCKED_NONCE$LWS, initializers$LWS);
12324
14305
  addBlockedPropertyDistortionFactoryInitializers$LWS(record$LWS, DataTransfer.prototype, DataTransferProtoBlockedProperties$LWS, initializers$LWS);
12325
14306
  addBlockedPropertyDistortionFactoryInitializers$LWS(record$LWS, Document$LWS, DocumentBlockedProperties$LWS, initializers$LWS);
12326
14307
  addBlockedPropertyDistortionFactoryInitializers$LWS(record$LWS, Document$LWS.prototype, DocumentProtoBlockedProperties$LWS, initializers$LWS);
@@ -12363,7 +14344,9 @@ function getDistortionFactories$LWS(record$LWS) {
12363
14344
  }
12364
14345
  // Finalize attribute distortions last because the attribute registry is
12365
14346
  // populated by the other distortion factories.
12366
- factories$LWS[factories$LWS.length] = finalizeAttributeDistortions$LWS;
14347
+ factories$LWS[factories$LWS.length] = finalizeAttributeSetterDistortions$LWS;
14348
+ // Finalize attribute getters (read-side registry) for the same reason.
14349
+ factories$LWS[factories$LWS.length] = finalizeAttributeGetterDistortions$LWS;
12367
14350
  distortionFactoriesCache$LWS.set(document$LWS, factories$LWS);
12368
14351
  return factories$LWS;
12369
14352
  }
@@ -13630,6 +15613,7 @@ function createMembraneMarshall$LWS(globalObject$LWS) {
13630
15613
  const {
13631
15614
  distortionCallback: distortionCallback$LWS,
13632
15615
  liveTargetCallback: liveTargetCallback$LWS,
15616
+ protectDistortions: protectDistortions$LWS,
13633
15617
  revokedProxyCallback: revokedProxyCallback$LWS
13634
15618
  // eslint-disable-next-line prefer-object-spread
13635
15619
  } = ObjectAssign$LWS({
@@ -15765,6 +17749,25 @@ function createMembraneMarshall$LWS(globalObject$LWS) {
15765
17749
  targetPointer$LWS();
15766
17750
  const target$LWS = selectedTarget$LWS;
15767
17751
  selectedTarget$LWS = undefined;
17752
+ if (protectDistortions$LWS && distortionCallback$LWS) {
17753
+ let safeDesc$LWS;
17754
+ try {
17755
+ safeDesc$LWS = ReflectGetOwnPropertyDescriptor$LWS(target$LWS, key$LWS);
17756
+ } catch (error) {
17757
+ throw pushErrorAcrossBoundary$LWS(error);
17758
+ }
17759
+ if (safeDesc$LWS) {
17760
+ ReflectSetPrototypeOf$LWS(safeDesc$LWS, null);
17761
+ const {
17762
+ get: getter$LWS,
17763
+ set: setter$LWS,
17764
+ value: value$LWS
17765
+ } = safeDesc$LWS;
17766
+ if (typeof getter$LWS === 'function' && distortionCallback$LWS(getter$LWS) !== getter$LWS || typeof setter$LWS === 'function' && distortionCallback$LWS(setter$LWS) !== setter$LWS || (typeof value$LWS === 'object' && value$LWS !== null || typeof value$LWS === 'function') && distortionCallback$LWS(value$LWS) !== value$LWS) {
17767
+ throw pushErrorAcrossBoundary$LWS(new TypeErrorCtor$LWS('Cannot delete property with a distortion.'));
17768
+ }
17769
+ }
17770
+ }
15768
17771
  try {
15769
17772
  return ReflectDeleteProperty$LWS(target$LWS, key$LWS);
15770
17773
  } catch (error) {
@@ -16447,6 +18450,7 @@ class VirtualEnvironment$LWS {
16447
18450
  distortionCallback: distortionCallback$LWS,
16448
18451
  instrumentation: instrumentation$LWS,
16449
18452
  liveTargetCallback: liveTargetCallback$LWS,
18453
+ protectDistortions: protectDistortions$LWS,
16450
18454
  revokedProxyCallback: revokedProxyCallback$LWS,
16451
18455
  signSourceCallback: signSourceCallback$LWS
16452
18456
  // eslint-disable-next-line prefer-object-spread
@@ -16460,6 +18464,7 @@ class VirtualEnvironment$LWS {
16460
18464
  distortionCallback: distortionCallback$LWS,
16461
18465
  instrumentation: instrumentation$LWS,
16462
18466
  liveTargetCallback: liveTargetCallback$LWS,
18467
+ protectDistortions: protectDistortions$LWS,
16463
18468
  revokedProxyCallback: revokedProxyCallback$LWS
16464
18469
  });
16465
18470
  const {
@@ -16639,6 +18644,7 @@ class VirtualEnvironment$LWS {
16639
18644
  }
16640
18645
  }
16641
18646
  lazyRemapProperties(target$LWS, ownKeys$LWS, unforgeableGlobalThisKeys$LWS) {
18647
+ // istanbul ignore else: primitive targets are silently ignored
16642
18648
  if (typeof target$LWS === 'object' && target$LWS !== null || typeof target$LWS === 'function') {
16643
18649
  const args$LWS = [this.blueGetTransferableValue(target$LWS)];
16644
18650
  ReflectApply$LWS(ArrayProtoPush$LWS, args$LWS, ownKeys$LWS);
@@ -16805,8 +18811,10 @@ function assignFilteredGlobalDescriptorsFromPropertyDescriptorMap$LWS(descs$LWS,
16805
18811
  // Avoid overriding ECMAScript global names that correspond to
16806
18812
  // global intrinsics. This guarantee that those entries will be
16807
18813
  // ignored if present in the source property descriptor map.
18814
+ // istanbul ignore else: ES intrinsic names are intentionally skipped
16808
18815
  if (!ESGlobalsAndReflectiveIntrinsicObjectNames$LWS.includes(ownKey$LWS)) {
16809
18816
  const unsafeDesc$LWS = source$LWS[ownKey$LWS];
18817
+ // istanbul ignore else: no action needed when unsafeDesc is falsy
16810
18818
  if (unsafeDesc$LWS) {
16811
18819
  // Avoid poisoning by only installing own properties from
16812
18820
  // unsafeDesc. We don't use a toSafeDescriptor() style helper
@@ -16845,6 +18853,7 @@ function linkIntrinsics$LWS(env$LWS, globalObject$LWS) {
16845
18853
  } = ReflectiveIntrinsicObjectNames$LWS; i$LWS < length$LWS; i$LWS += 1) {
16846
18854
  const globalName$LWS = ReflectiveIntrinsicObjectNames$LWS[i$LWS];
16847
18855
  const reflectiveValue$LWS = globalObject$LWS[globalName$LWS];
18856
+ // istanbul ignore else: all standard reflective intrinsics exist at runtime
16848
18857
  if (reflectiveValue$LWS) {
16849
18858
  // Proxy.prototype is undefined.
16850
18859
  if (reflectiveValue$LWS.prototype) {
@@ -16989,6 +18998,7 @@ function createIframeVirtualEnvironment$LWS(globalObject$LWS, providedOptions$LW
16989
18998
  keepAlive: keepAlive$LWS = true,
16990
18999
  liveTargetCallback: liveTargetCallback$LWS,
16991
19000
  maxPerfMode: maxPerfMode$LWS = false,
19001
+ protectDistortions: protectDistortions$LWS = false,
16992
19002
  signSourceCallback: signSourceCallback$LWS
16993
19003
  // eslint-disable-next-line prefer-object-spread
16994
19004
  } = ObjectAssign$LWS({
@@ -17004,6 +19014,7 @@ function createIframeVirtualEnvironment$LWS(globalObject$LWS, providedOptions$LW
17004
19014
  blueCreateHooksCallbackCache$LWS.set(blueRefs$LWS.document, blueConnector$LWS);
17005
19015
  }
17006
19016
  // Install default TrustedTypes policy in the virtual environment.
19017
+ // istanbul ignore next: requires both trustedTypes API (unavailable in jsdom) and a defaultPolicy option
17007
19018
  // @ts-ignore trustedTypes does not exist on GlobalObject
17008
19019
  if (typeof redWindow$LWS.trustedTypes !== 'undefined' && isObject$LWS(defaultPolicy$LWS)) {
17009
19020
  // @ts-ignore trustedTypes does not exist on GlobalObject
@@ -17018,6 +19029,7 @@ function createIframeVirtualEnvironment$LWS(globalObject$LWS, providedOptions$LW
17018
19029
  distortionCallback: distortionCallback$LWS,
17019
19030
  instrumentation: instrumentation$LWS,
17020
19031
  liveTargetCallback: liveTargetCallback$LWS,
19032
+ protectDistortions: protectDistortions$LWS,
17021
19033
  revokedProxyCallback: keepAlive$LWS ? revokedProxyCallback$LWS : undefined,
17022
19034
  signSourceCallback: signSourceCallback$LWS
17023
19035
  });
@@ -17025,6 +19037,7 @@ function createIframeVirtualEnvironment$LWS(globalObject$LWS, providedOptions$LW
17025
19037
  // window
17026
19038
  // window.document
17027
19039
  // In browsers globalThis is === window.
19040
+ // istanbul ignore next: coverage never runs where globalThis !== window
17028
19041
  if (typeof globalThis === 'undefined') {
17029
19042
  // Support for globalThis was added in Chrome 71.
17030
19043
  // However, environments like Android emulators are running Chrome 69.
@@ -17070,6 +19083,7 @@ function createIframeVirtualEnvironment$LWS(globalObject$LWS, providedOptions$LW
17070
19083
  ReflectApply$LWS(DocumentProtoOpen$LWS, redDocument$LWS, []);
17071
19084
  ReflectApply$LWS(DocumentProtoClose$LWS, redDocument$LWS, []);
17072
19085
  } else {
19086
+ // istanbul ignore next: coverage never runs in old Chromium (<v86)
17073
19087
  if (IS_OLD_CHROMIUM_BROWSER$LWS) {
17074
19088
  // For Chromium < v86 browsers we evaluate the `window` object to
17075
19089
  // kickstart the realm so that `window` persists when the iframe is
@@ -17405,7 +19419,7 @@ function toSourceText$LWS(value$LWS, sourceType$LWS) {
17405
19419
  // tools from mistaking the regexp or the replacement string for an
17406
19420
  // actual source mapping URL.
17407
19421
  /\/\/# sandbox(?=MappingURL=.*?\s*$)/, '//# source']);
17408
- sourceText$LWS = `\n//# LWS Version = "0.28.1"\n${sourceText$LWS}`;
19422
+ sourceText$LWS = `\n//# LWS Version = "0.28.3"\n${sourceText$LWS}`;
17409
19423
  return sourceType$LWS === 1 /* SourceType.Module */ && indexOfPragma$LWS(sourceText$LWS, 'use strict') === -1 ?
17410
19424
  // Append "'use strict'" to the extracted function body so it is
17411
19425
  // evaluated in strict mode.
@@ -18209,7 +20223,7 @@ function wrapPlatformResourceLoader$LWS(dep$LWS, key$LWS) {
18209
20223
  depRegistry$LWS.set(dep$LWS, secureDep$LWS);
18210
20224
  return secureDep$LWS;
18211
20225
  }
18212
- /*! version: 0.28.1 */
20226
+ /*! version: 0.28.3 */
18213
20227
 
18214
20228
  const loaderDefine = (globalThis ).LWR.define;
18215
20229