Skip to content

Security

Generative DOM enforces security at the architecture level. XSS prevention is not a filter applied on top -- it is a consequence of how rendering works.

Core Principles

  1. DOM API only. All element creation uses document.createElement and document.createTextNode. The innerHTML and insertAdjacentHTML properties are never used for any content derived from input.

  2. Text content is always safe. User text is set via textContent or createTextNode, which cannot execute scripts or interpret HTML.

  3. No dynamic code execution. eval(), Function(), and setTimeout(string) are never used.

URL Whitelisting

Link href and image src attributes are validated against protocol whitelists:

ElementAllowed Protocols
Links (<a>)https:, http:, mailto:
Images (<img>)https:, http:

All other protocols are stripped. This blocks:

  • javascript: URLs
  • data: URLs
  • vbscript: URLs
  • URL-encoded variants (java%73cript:)
  • Case variations (JaVaScRiPt:)
  • Null byte injections (java\0script:)

Attribute Safety

  • No on* event handler attributes are allowed on any element
  • The style attribute is blocked if it contains url() or expression()
  • Attribute values are always set via element.setAttribute() with validated values
  • Custom element plugins define their own safe attribute whitelists, enforced by the core

Code Blocks

Code block content is always treated as plain text. Even the syntax highlighting plugin renders spans with CSS classes -- it never interprets code content as HTML. A <script> tag inside a code block appears as literal text.

Custom Elements

Custom element tags are whitelisted. Only tags explicitly registered through the custom-elements plugin are processed. Unknown tags like <evil-script /> are treated as plain text and rendered harmlessly.

What Generative DOM Blocks

Attack VectorHow It Is Blocked
<script>alert('xss')</script>Rendered as text via createTextNode
<img src=x onerror=alert('xss')>Rendered as text, not as an element
[click](javascript:alert('xss'))Protocol stripped, link rendered without href
[click](data:text/html,...)Protocol stripped
<md-button onclick="alert('xss')">on* attributes stripped during rendering
CSS url(javascript:...) in styleStyle attribute blocked
HTML entities &lt;script&gt;Rendered as text, not decoded to active tags

Testing Security

Generative DOM includes a comprehensive set of XSS attack vector fixtures in the mocks package. The security test suite verifies:

  • No <script> elements exist in output DOM
  • No on* event attributes exist in output DOM
  • No javascript: URLs in any href or src
  • Code block content is always textContent
  • innerHTML is never called (monitored via vitest.spyOn)
  • Custom element attribute whitelists are enforced