The Complete Production SOP: How to Deploy and Run Cross-Site Scripting (XSS) Defense & DOMPurify in Autonomous AI Agents
Step-by-step SOP to install and run xss-defense-dompurify-sanitizer in Codex, Claude Code, and Cursor. Sanitize untrusted HTML and secure React apps reliably.
Technical Overview & Architectural Context
Autonomous coding agents frequently generate vulnerable frontend and full-stack code when rendering rich user content. When tasked with rendering markdown, user comments, or third-party HTML payloads, LLMs routinely default to raw React `dangerouslySetInnerHTML`, Vue `v-html`, or Svelte `{@html}` blocks without sanitization, or attempt naive regex-based tag replacements that bypass modern HTML5 parsing edge cases. Furthermore, when agents attempt to incorporate DOMPurify, they often fail to handle Node.js Server-Side Rendering (SSR) environments properly, leading to runtime crashes (`window is not defined`) or DOM clobbering vulnerabilities. Without explicit, deterministic constraints, an autonomous agent may also configure loose sanitization policies that permit dangerous URI schemes such as `javascript:`, data URIs, or SVG-based script injection vectors. The `xss-defense-dompurify-sanitizer` skill prevents these critical AppSec regressions by enforcing a strict procedural SOP: mandating strict hook configuration, explicit `ALLOWED_TAGS` and `ALLOWED_ATTR` profiles, reverse tab-nabbing mitigations, and isomorphic DOM wrappers (`jsdom` or isomorphic-dompurify) across Codex, Claude Code, Cursor, and Windsurf.
Prerequisites & Environment Requirements
Verified Search Intents & Long-Tail Queries Solved
This operational tutorial is engineered to provide deterministic solutions for these developer search queries:
Step-by-Step Execution Playbook
Local Environment Setup & SKILL.md Mounting
Mount the SKILL.md manifest into the agent workspace skill directory for immediate hot-reloading.
Autonomous agent runtimes inspect workspace-level and user-level skill registries. To equip your agent with the XSS Defense SOP, install the manifest under your agent's discovery directory (`.agents/skills/` or `.claude/skills/`). Claude Code and Cursor dynamically parse the frontmatter metadata to index matching intent triggers (`sanitize html with dompurify`, `prevent xss in react`, `safe dangerouslysetinnerhtml`).
mkdir -p .agents/skills/xss-defense-dompurify-sanitizer && curl -fsSL https://askills.dev/api/skills/xss-defense-dompurify-sanitizer/raw -o .agents/skills/xss-defense-dompurify-sanitizer/SKILL.md---
name: "xss-defense-dompurify-sanitizer"
description: "Sanitize untrusted HTML and prevent Cross-Site Scripting with DOMPurify."
metadata:
author: "Cure53"
version: "1.0.0"
runtime_compatibility:
- "codex"
- "claude-code"
- "cursor"
- "windsurf"
triggers:
- "sanitize html with dompurify"
- "prevent xss in react"
- "safe dangerouslysetinnerhtml"
permissions:
fs_read: true
fs_write: "workspace"
shell_exec: false
net_access: false
---
# Cross-Site Scripting (XSS) Defense & DOMPurify
1. Run DOMPurify.sanitize(dirtyHtml, { USE_PROFILES: { html: true } }) on all untrusted HTML.
2. Specify ALLOWED_TAGS and ALLOWED_ATTR explicitly when rendering rich formatting.
3. Ensure links generated from user input enforce target='_blank' and rel='noopener noreferrer'.
4. Never construct HTML strings using unescaped user inputs in client JavaScript.In Cursor and Windsurf, keep `SKILL.md` under `.cursor/skills/` or `.windsurf/skills/` to enable zero-latency hot-reloading without restarting your editor session.
Ensure `fs_write` is restricted to `'workspace'`. Do not configure `shell_exec: true` unless you explicitly require the agent to execute build or lint test scripts.
Dependency Installation & Isomorphic Wrapper Setup
Install DOMPurify and configure an isomorphic abstraction layer for Next.js, Remix, or vanilla SSR.
Client-only DOMPurify crashes in server runtime environments due to a missing `window` object. To ensure the agent implements a robust solution that works across Node.js SSR and the browser, install `isomorphic-dompurify` or `dompurify` alongside `@types/dompurify`.
npm install isomorphic-dompurify && npm install -D @types/dompurifyimport DOMPurify from 'isomorphic-dompurify';
// Configure hook to enforce safe external links automatically
DOMPurify.addHook('afterSanitizeAttributes', (node) => {
if ('target' in node && node.tagName === 'A') {
node.setAttribute('target', '_blank');
node.setAttribute('rel', 'noopener noreferrer');
}
});
export const SAFE_HTML_CONFIG = {
USE_PROFILES: { html: true },
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'ul', 'ol', 'li', 'code', 'pre', 'blockquote', 'h1', 'h2', 'h3'],
ALLOWED_ATTR: ['href', 'title', 'class', 'target', 'rel'],
RETURN_TRUSTED_TYPE: false,
} as const;
export function sanitizeHtml(untrustedInput: string): string {
return DOMPurify.sanitize(untrustedInput, SAFE_HTML_CONFIG);
}Using `isomorphic-dompurify` prevents the agent from hallucinating brittle conditional checks like `typeof window !== 'undefined'` that lead to hydration mismatches in React 18+.
Beware of DOM clobbering: DOMPurify's default configuration defends against clobbering form/input attributes, but overriding `ALLOWED_TAGS` with custom elements can re-introduce clobbering risks if `SANITIZE_DOM: true` is omitted.
Intent Matching & Trigger Invocation
Invoke the skill deterministically using target prompts to generate safe, typed React components.
Provide the agent with user story requirements that contain frontmatter trigger keywords (e.g., 'safe dangerouslysetinnerhtml' or 'sanitize html with dompurify'). The runtime matches the skill manifest, binding the agent to the AppSec SOP.
import React, { useMemo } from 'react';
import { sanitizeHtml } from '../lib/sanitize';
interface SafeHtmlRendererProps {
dirtyHtml: string;
className?: string;
}
export const SafeHtmlRenderer: React.FC<SafeHtmlRendererProps> = ({ dirtyHtml, className }) => {
const sanitizedContent = useMemo(() => ({
__html: sanitizeHtml(dirtyHtml)
}), [dirtyHtml]);
return (
<div
className={className}
dangerouslySetInnerHTML={sanitizedContent}
/>
);
};Wrap the `sanitizeHtml` call in React `useMemo` so repetitive rendering cycles of long markdown or comment feeds do not incur costly DOM re-parsing overhead.
Never allow agents to interpolate raw user input via template strings directly inside `dangerouslySetInnerHTML={{ __html: `${userPrefix}${sanitized}` }}`. The full string must pass through sanitization.
Verification, Linting & Output Quality Gate
Run security-focused unit tests and linting to guarantee malicious payloads are neutralized.
Enforce a verification gate requiring the agent to run unit tests that feed known malicious attack vectors (XSS polyglots, SVG event handlers, and javascript: protocols) through the sanitization pipeline and verify zero leakage.
npx jest src/lib/sanitize.test.ts --no-cache || npx vitest run src/lib/sanitize.test.tsimport { describe, it, expect } from 'vitest';
import { sanitizeHtml } from './sanitize';
describe('sanitizeHtml XSS Defense Gate', () => {
it('strips malicious script tags and inline handlers', () => {
const payload = '<p>Hello</p><script>alert(1)</script><img src="x" onerror="alert(2)">';
const clean = sanitizeHtml(payload);
expect(clean).toBe('<p>Hello</p><img src="x">');
expect(clean).not.toContain('script');
expect(clean).not.toContain('onerror');
});
it('neutralizes javascript: URI schemes and enforces noopener', () => {
const payload = '<a href="javascript:alert(1)">Click me</a><a href="https://example.com">Valid</a>';
const clean = sanitizeHtml(payload);
expect(clean).not.toContain('javascript:');
expect(clean).toContain('target="_blank"');
expect(clean).toContain('rel="noopener noreferrer"');
});
});Instruct Claude Code or Codex to execute `git diff --stat` after running tests to verify that no unnecessary mock files or insecure overrides were added to your codebase.
Do not skip SVG tests. `SVG` and `MATH` elements contain distinct parsing context rules; DOMPurify disables SVG payloads unless explicitly allowed in profile options.
Real-World Scenario: Rendering User-Submitted Rich-Text Comments in a Next.js App Router Application
“We need to render user-submitted rich comments in our Next.js App Router frontend. Implement a safe dangerouslySetInnerHTML component using sanitize html with dompurify that strips script tags, iframe elements, and javascript: links, while enforcing noopener noreferrer on all external links.”
Runtime Troubleshooting & Failure Modes
Root Cause: The standard `dompurify` package was imported in a server-side execution context (Next.js App Router, SSR, or Node test environment) where the browser DOM `window` object does not exist globally.
npm uninstall dompurify && npm install isomorphic-dompurify
// Update import in src/lib/sanitize.ts:
import DOMPurify from 'isomorphic-dompurify';Root Cause: Client and server rendered different HTML strings because DOMPurify was executed with different hook states, or client-side browser DOM normalization parsed elements differently than server-side jsdom.
// Ensure hooks are added before export, or run sanitization inside a client-side useEffect/useMemo hook:
'use client';
import { useState, useEffect } from 'react';
import { sanitizeHtml } from '@/lib/sanitize';
export function SafeClientHtml({ dirtyHtml }: { dirtyHtml: string }) {
const [clean, setClean] = useState('');
useEffect(() => {
setClean(sanitizeHtml(dirtyHtml));
}, [dirtyHtml]);
if (!clean) return null;
return <div dangerouslySetInnerHTML={{ __html: clean }} />;
}Frequently Asked Questions (Cross-Site Scripting (XSS) Defense & DOMPurify SOP)
Q:Can I use Cross-Site Scripting (XSS) Defense & DOMPurify across Codex, Claude Code, and Cursor simultaneously?
Yes. The skill conforms strictly to the standard SKILL.md specification. Runtimes like Claude Code, Codex Desktop, Cursor, and Windsurf parse the declarative YAML frontmatter and execute identical sanitization workflows regardless of the host agent.
Q:How does Cross-Site Scripting (XSS) Defense & DOMPurify prevent context window overflow during long agent sessions?
The skill provides a tightly scoped, deterministic procedure (under 250 tokens in the frontmatter definition) rather than stuffing dozens of generic AppSec paragraphs into your conversation history. The agent references concise, proven patterns and verification steps on-demand.
Q:Does this skill require escalated root or container permissions?
No. The skill has an audited security score of 98/100. It requires zero network access (`net_access: false`) and zero shell execution rights (`shell_exec: false`) during basic rule execution, operating entirely within workspace file system constraints.
Ready to equip your autonomous agent with Cross-Site Scripting (XSS) Defense & DOMPurify?
Copy the complete audited SKILL.md specification or download the 1-click zip bundle directly from our verified registry.