Skip to content
cccskills
FreePublished on GitHub

dom-security-hardening

When hardening a web application against Cross-Site Scripting (XSS) and injection attacks.

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md7.5 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

DOM Security Hardening

Purpose

XSS attacks kill applications. This skill hardens the DOM attack surface by enforcing a strict Content Security Policy, eliminating unsafe DOM APIs, and stripping execution vectors like inline scripts and styles. Following this skill is MANDATORY for any user-facing web application handling user input.

When to use

  • Setting up the initial index.html or document root of a web application
  • Refactoring legacy code that relies on direct DOM manipulation
  • Auditing a frontend codebase for XSS vulnerabilities
  • Processing rich text or markdown input from untrusted users
  • Creating forms or chat systems that accept user input

When NOT to use

  • CSS framework design (separate concern)
  • React component prop validation (use React Component Design)
  • Backend input validation (different layer, still required)

Inputs required

  • HTML document structure
  • JavaScript files with DOM manipulation
  • Understanding of Content Security Policy basics
  • Sanitizer library decision (DOMPurify, sanitize-html, etc.)

Workflow

  1. Enforce CSP: Add strict <meta http-equiv="Content-Security-Policy"> tag in HTML <head> (or HTTP headers)
  2. Externalize Assets: Extract ALL inline <script> and <style> blocks into separate .js and .css files
  3. Remove Inline Events: Replace inline onclick="...", onchange="..." with standard addEventListener bindings
  4. Replace Unsafe DOM: Replace innerHTML, outerHTML, dangerouslySetInnerHTML with textContent or innerText
  5. Implement Sanitizer: If HTML rendering is REQUIRED, use DOMPurify or equivalent BEFORE insertion
  6. Test CSP: Verify policy blocks all unauthorized execution attempts
  7. Verify No Bypasses: Use security scanner (OWASP ZAP, Burp) to confirm XSS vectors are closed

Rules

  • MUST implement strict CSP: default-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'
  • MUST NEVER use inline <script> blocks in HTML
  • MUST NEVER use inline style="..." attributes
  • MUST NEVER use eval(), setTimeout(string), new Function(string)
  • MUST NEVER use innerHTML, outerHTML, or dangerouslySetInnerHTML with user input
  • MUST use textContent or innerText for all dynamic text insertions
  • MUST sanitize user HTML with DOMPurify before any insertion
  • MUST NOT use 'unsafe-inline' or 'unsafe-eval' in CSP

Anti-patterns

  • innerHTML Assignment: element.innerHTML = userInput (immediate XSS)
  • javascript: URIs: href="javascript:void(0)" or href="javascript:alert(1)"
  • Unsafe CSP: Content-Security-Policy: default-src *; script-src 'unsafe-inline'
  • Event Handler Strings: Creating event handlers from user input or strings
  • Trusting User Input: Assuming any user input is safe to insert into DOM
  • Missing Sanitizer: Using rich text editor without sanitizing output

Failure conditions

  • CSP header/meta tag is missing
  • Inline scripts or styles remain in production code
  • innerHTML used with user input
  • dangerouslySetInnerHTML used without sanitization
  • CSP allows 'unsafe-inline' or 'unsafe-eval'
  • Sanitizer library is not installed for rich text rendering

Validation checklist

  • CSP header/meta tag present with restrictive policy
  • No <script> tags with inline code (all external)
  • No inline style="..." attributes (all CSS classes)
  • No onclick, onchange, oninput inline event handlers
  • All DOM text insertions use textContent or innerText
  • No innerHTML, outerHTML, or dangerouslySetInnerHTML with user input
  • DOMPurify (or equivalent) used for any rich text rendering
  • No eval(), setTimeout(string), new Function(string) calls
  • Security scanner passes (no XSS vulnerabilities detected)
  • CSP blocks inline script execution (verify in browser console)

Output format

  • HTML file: Strict CSP meta tag in <head>, external <script> tags at end of <body>
  • JavaScript: All DOM mutations via safe APIs (textContent, className, setAttribute)
  • CSS: Separate .css files, no inline styles anywhere
  • Rich Text: HTML sanitized via DOMPurify before insertion
  • Validation: Automated XSS scan passes

Security considerations

  • Threat Model: Prevent XSS attacks via user input injection, DOM gadgets, third-party scripts
  • Mitigations: CSP prevents execution, sanitizer prevents HTML injection, safe APIs prevent eval
  • Constraints: CSP may conflict with analytics/ads (allow specific domains only)
  • Legacy Code: Some frameworks may require CSP relaxation (document trade-offs)
  • Third-party Scripts: Load analytics/ads only from trusted CDNs with subresource integrity (SRI)

Agent execution notes

  • Agent MAY: Add CSP header, externalize inline scripts/styles, replace innerHTML with textContent, implement DOMPurify
  • Agent MUST NEVER: Use 'unsafe-inline' or 'unsafe-eval' in CSP, ignore sanitization requirements, leave inline event handlers
  • Agent MUST ASK: Before adding third-party scripts, before relaxing CSP for legacy code, before using dangerouslySetInnerHTML
  • Agent MUST VALIDATE: CSP policy is strict, no inline scripts remain, no unsafe DOM APIs, XSS scanner passes

Example

❌ Anti-pattern (Unsafe XSS vectors, no CSP):

<!-- No CSP -->
<a href="javascript:void(0)" onclick="submitForm()">Click me</a>
<div id="user-bio"></div>

<script>
  // Unsafe: direct user input to DOM
  document.getElementById('user-bio').innerHTML = getUserInput();
  
  // Unsafe: inline style
  document.getElementById('user-bio').setAttribute('style', 'color: red;');
  
  // Unsafe: event handler string
  setTimeout("console.log('vulnerable')", 1000);
</script>

✅ Correct pattern (Hardened, safe):

<!-- Strict CSP enforced -->
<meta http-equiv="Content-Security-Policy"
  content="default-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'; img-src 'self' https:; font-src 'self';"
>

<a href="#" id="submit-btn">Click me</a>
<div id="user-bio"></div>

<!-- External script only -->
<script src="/js/app.js"></script>
// app.js

// 1. Safe event binding
document.getElementById('submit-btn').addEventListener('click', (e) => {
  e.preventDefault();
  submitForm();
});

// 2. Safe text insertion (escapes HTML by default)
document.getElementById('user-bio').textContent = getUserInput();

// 3. Safe styling via CSS classes
document.getElementById('user-bio').classList.add('text-red');

// 4. If HTML rendering is absolutely required, sanitize first
import DOMPurify from 'dompurify';
document.getElementById('user-bio').innerHTML = DOMPurify.sanitize(getUserMarkdown());

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

When designing and implementing web interfaces to ensure they are usable by everyone.

The English summary is being prepared. Showing the original description.

KraitDev/skiLL.Md6Updated Jun 8, 2026

When creating or extending an HTTP API for client consumption.

The English summary is being prepared. Showing the original description.

KraitDev/skiLL.Md6Updated Jun 8, 2026

When improving read performance and reducing database load.

The English summary is being prepared. Showing the original description.

KraitDev/skiLL.Md6Updated Jun 8, 2026

When configuring automated build, test, and deployment workflows for a repository.

The English summary is being prepared. Showing the original description.

KraitDev/skiLL.Md6Updated Jun 8, 2026

When asynchronously reviewing peer code before merging into the main branch.

The English summary is being prepared. Showing the original description.

KraitDev/skiLL.Md6Updated Jun 8, 2026

When addressing slow application endpoints, high database CPU usage, or standardizing data access patterns.

The English summary is being prepared. Showing the original description.

KraitDev/skiLL.Md6Updated Jun 8, 2026

See all skills by KraitDev

Report a problem with this skill