---
title: "Never read elements through window globals · Agent Wranglers"
url: https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/no-named-element-globals
id: CSS-37
level: Required
applies: user-content
risk: takeover
updated: 2026-10-27
build: a2a6bdfed830
tokens: 1124
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Never read elements through window globals

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [HTML structure and reuse](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: CSS-37
- Level: Required
- Chapter: [HTML structure and reuse](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse.md)
- Rule: Find elements only with `getElementById` or `querySelector`, never as a property of `window` or `document`. Remove or prefix the `id` and `name` attributes in any HTML that users supply.
- Check: A search of the scripts finds 0 reads of `window.<name>` or `document.<name>` where the name is an id on any built page. A unit test cleans `<a id="config" name="config" href="/">` and the output keeps neither attribute unchanged.
- Risk: An account or system taken over
- Applies when: The project hosts content that users post.
- Review by: 2027-06-30
- How: The browser makes every element with an `id` a property of `window`, and some elements with a `name` too. A comment holding `<a id="config" href="https://evil.example/">` then takes the place of a global `config` that a script reads. This attack is called DOM clobbering. Declare every variable with `const` or `let` inside a module, and keep settings off `window`. Clean user HTML with an allow list of tags and attributes, such as DOMPurify with `SANITIZE_NAMED_PROPS`. The browser's Sanitizer API, `element.setHTML()`, shipped in Chrome 146 and Firefox 148 but not yet in Safari, so keep a library as the fallback. Escaping every other value stays the job of [Escape everything you show](https://agentwranglers.se/playbook/application-security/input-and-injection/cross-site-scripting.md). Ids that your own templates write follow [Keep ids unique and stable](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/unique-stable-ids.md).

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
// Unsafe: an <a id="config"> in a comment replaces this global
const unsafeEndpoint = window.config?.apiUrl;

// Safe: a module constant, and user HTML without named attributes
const config = Object.freeze({ apiUrl: '/api' });
const cleanComment = DOMPurify.sanitize(commentHtml, { SANITIZE_NAMED_PROPS: true });
```

### Python example

```python
import nh3

ALLOWED_ATTRIBUTES = {"a": {"href"}, "p": set(), "em": set(), "strong": set()}

def clean_comment(html: str) -> str:
    return nh3.clean(html, tags=set(ALLOWED_ATTRIBUTES), attributes=ALLOWED_ATTRIBUTES)

assert "id=" not in clean_comment('<a id="config" name="config" href="/">x</a>')
```

## Sources

- [OWASP DOM Clobbering Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/DOM_Clobbering_Prevention_Cheat_Sheet.html)
- [HTML Standard on named access on the Window object](https://html.spec.whatwg.org/multipage/nav-history-apis.html#named-access-on-the-window-object)

## Related rules

- APS-3 [Escape everything you show](https://agentwranglers.se/playbook/application-security/input-and-injection/cross-site-scripting.md) in Application security
- CSS-22 [Keep ids unique and stable](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/unique-stable-ids.md) in HTML and CSS
- CSS-24 [Clone markup that scripts add from a template element](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/template-element.md) in HTML and CSS

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/no-named-element-globals">Agent Wranglers HTML and CSS playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Keep ids unique and stable](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/unique-stable-ids.md)
- Next: [Avoid wrapper elements that only hold a class](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/no-wrapper-divs.md)
- [HTML structure and reuse](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse.md)
