Input sanitization with strip-first default using native browser APIs (DOMParser). [EXPLICIT] Context-specific encoding for HTML, URL, CSS, and JS contexts. Dual-layer client + server validation. No external sanitization libraries by default. [EXPLICIT] Trigger: "sanitize input", "XSS prevention", "input validation", "strip HTML", "DOMParser"
From jm-adknpx claudepluginhub javimontano/jm-adk-alfaThis skill is limited to using the following tools:
agents/guardian.mdagents/lead.mdagents/specialist.mdagents/support.mdevals/evals.jsonknowledge/body-of-knowledge.mdknowledge/knowledge-graph.mdprompts/meta.mdprompts/primary.mdprompts/variations/deep.mdprompts/variations/quick.mdtemplates/output.docx.mdtemplates/output.html"Sanitize at the boundary. Trust nothing that crosses it."
Implements the Constitution VII sanitization default: strip HTML tags from user input before storage — not escape, not allowlist. Uses native browser APIs (DOMParser) over external libraries. Covers all input contexts: HTML, URL, CSS, JS. Enforces dual-layer validation (client + server). <script> and <style> tags are removed with their content, not just tag-stripped. Rich text fields are the exception, requiring explicit justification per Constitution XIV (Simple First). [EXPLICIT]
localStorage reads, postMessage handlers, file uploadsencodeURIComponent() for values, validate URL structureCSS.escape() for dynamic valuestextContent, never innerHTML<script> and <style> tags: remove tags AND their content (not just tag stripping)function stripHTML(input) {
const doc = new DOMParser().parseFromString(input, 'text/html');
// Remove script and style elements entirely
doc.querySelectorAll('script, style').forEach(el => el.remove());
return doc.body.textContent || '';
}
// Firestore trigger or callable function
function validateInput(text) {
if (typeof text !== 'string') throw new Error('Invalid input type');
// Strip HTML server-side as defense-in-depth
const stripped = text.replace(/<script[\s\S]*?<\/script>/gi, '')
.replace(/<style[\s\S]*?<\/style>/gi, '')
.replace(/<[^>]*>/g, '');
return stripped.trim();
}
innerHTML with user data — always textContent or DOMParser<script>alert(1)</script>, <img onerror=alert(1)>, <svg onload=alert(1)> — all strippedinnerHTML assignments with user-controlled data in codebase (grep verify)<script> and <style> removed with content, not just tagsinnerHTML with user data anywhere in codebase| Anti-Pattern | Why It's Bad | Do This Instead |
|---|---|---|
| Escape instead of strip | Escaped HTML still renders in some contexts | Strip tags, keep text only |
| Client-only validation | Bypassable via DevTools or API calls | Always mirror on server |
| External sanitization library | Dependency bloat for a solved problem | Use native DOMParser |
| Allowlist by default | Maintenance burden, easy to miss patterns | Strip by default, allowlist only for rich text |
Using innerHTML with user data | Direct XSS vector | Use textContent or DOMParser |
security-testing — Broader security testing including sanitization verificationdual-layer-verification — Static + runtime verification of security invariantsform-engineering — Form UX patterns that integrate sanitizationfirestore-security-rules — Server-side rule enforcementExample invocations:
| Scenario | Handling |
|---|---|
| Empty or minimal input | Request clarification before proceeding |
| Conflicting requirements | Flag conflicts explicitly, propose resolution |
| Out-of-scope request | Redirect to appropriate skill or escalate |
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.