---
title: Security & Content Security Policy (CSP)
description: Hardening guidelines, DOMPurify sanitization profile, and recommended Content Security Policy headers for VertiWiki.
tags: [vertiwiki, security, csp, dompurify, xss, threat-model]
---

# Security & Content Security Policy (CSP)

> For the complete documentation index and agent navigation, see [llms.txt](/llms.txt).

Because VertiWiki executes entirely inside the browser client and fetches untrusted or user-contributed Markdown documents dynamically, security and Cross-Site Scripting (XSS) prevention are foundational architectural invariants.

---

## 🛡️ The Zero-XSS Defense Model

VertiWiki incorporates defensive security across every layer of the rendering pipeline:

```mermaid
graph LR
    MD[Raw Markdown Input] --> Marked[Marked Compiler]
    Marked --> RawHTML[Intermediate HTML String]
    RawHTML --> DOMPurify[Hardened DOMPurify Profile]
    DOMPurify --> SafeDOM[Sanitized Safe DOM Tree]
    SafeDOM --> Mount[Injection into #verti-app]
```

### 1. Hardened DOMPurify Sanitization
Every HTML string generated by `marked` passes through `DOMPurify.sanitize()` prior to DOM injection:
- All `<script>`, `<object>`, `<embed>`, and `onload`/`onerror` event handlers are stripped.
- SVG diagrams generated by Mermaid are processed under a strict profile that allows structural SVG nodes (`<foreignObject>`, `<style>`, `<path>`) while blocking inline executable script vectors.
- MathML elements used by KaTeX are preserved without exposing DOM clobbering vulnerabilities.

### 2. URL Sanitization
Links and image references are validated using `sanitizeUrl()`. Dangerous protocols (`javascript:`, `vbscript:`, `data:text/html`) are completely neutralized.

### 3. Contextual HTML Escaping
All dynamic string interpolations in UI templates (such as search result previews, breadcrumb titles, and 404 error parameters) use `escapeHtml()` to prevent DOM-based XSS injection.

### 4. Iframe Sandboxing & Presentation Protocol
Raw `<iframe>` tags embedded in Markdown documents are governed by DOMPurify hooks in `src/core/parser.ts`. VertiWiki enforces a secure default sandbox attribute:
```html
sandbox="allow-scripts allow-same-origin allow-popups allow-forms allow-presentation"
```
This configuration strictly omits `allow-top-navigation`, preventing untrusted embedded frames from hijacking the parent window (frame busting), while enabling legitimate media embeds and interactive slide decks via `allow-presentation`. Custom `sandbox` attributes supplied by trusted authors are preserved.

### 5. Script Scheme Anchor Neutralization
In addition to URL sanitization, the runtime navigation layer in `src/core/router.ts` inspects all anchor elements (`<a>`). Any link attempting to trigger executable schemes (`javascript:`, `vbscript:`) has its `href` attribute immediately stripped prior to DOM dispatch.

---

## 🔒 Recommended Content Security Policy (CSP)

For maximum production security, configure your static web server (Nginx, Cloudflare, Apache, or Vercel) to emit the following HTTP response headers:

```http
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com data:; img-src 'self' data: https:; connect-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'self';
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()
```

> [!NOTE]
> `'unsafe-inline'` for `style-src` is required because VertiWiki injects dynamic CSS custom properties for theme presets and syntax highlighting.
> `'unsafe-inline'` for `script-src` is only required if you use inline single-file deployments (`index.html`). When distributing standalone assets with separate bundles, you can enforce strict sha256 hashes or nonces.

---

## 🛑 Threat Model & Sandboxing

| Threat Vector | Mitigation in VertiWiki |
| :--- | :--- |
| **Malicious Markdown Authoring** | Strict DOMPurify sanitization strips all unauthorized tags and attributes. |
| **Iframe Hijacking / Frame Busting** | Automated iframe sandboxing omits `allow-top-navigation` while allowing presentation and forms. |
| **Script Scheme Execution** | `javascript:` and `vbscript:` schemes are stripped from anchors at the router level. |
| **Search Snippet Injection** | MiniSearch result previews are strictly escaped via `escapeHtml()` before rendering. |
| **Accidental Zoom on Linked Badges** | Lightbox handler excludes images wrapped inside anchor links (`:not(a img)`). |
| **Clickjacking / Framing** | Blocked via `X-Frame-Options: DENY` and CSP `frame-ancestors 'none'`. |
| **MIME-Type Sniffing** | Neutralized by serving `X-Content-Type-Options: nosniff`. |
| **Exfiltration via Analytics** | Telemetry scripts only trigger if provider IDs are explicitly declared in `config.json`. |

---

## 🔗 Next Steps

- Explore deployment configurations in the [Operational Runbook](../operations/runbook.md).
- Review the core sanitization methods in [API Reference](../reference/api.md).
