1 · Hijacking window.CONFIG with markup

The app reads an optional global: const url = (window.CONFIG && window.CONFIG.url) || '/api/default'. Inject HTML below (it is attached to the page so the browser's named access is live, but <script> and on* handlers are stripped — clobbering needs neither). Compare the vulnerable reader against the hardened one.

What window.CONFIG resolves to
Inject markup to inspect…
Reader output → loadScript(url) target

2 · Clobbering a method: form.submit

A control named submit shadows the form's submit() method. Inject the field, then see how typeof form.submit flips from function to object — calling it would throw. The fix borrows the real method.

Naive: form.submit
Hardened: HTMLFormElement.prototype.submit

3 · Why this works — named access

<a id="foo">            →  window.foo        // the element
<a id="x"><a id="x">   →  window.x          // HTMLCollection
<form id="f">
  <input name="y">      →  f.y               // the control
<input name="length">  →  f.length          // clobbers the property

Defense:
  document.getElementById('foo')          // Element | null, never a collection
  el instanceof HTMLScriptElement         // verify the type you expect
  HTMLFormElement.prototype.submit.call(f)// borrow the real method
  DOMPurify.sanitize(html, {              // remove the named-access surface
    SANITIZE_NAMED_PROPS: true, FORBID_ATTR: ['id','name'],
  })