本文へ移動
cccskills
無料GitHub で公開

dom-security-hardening

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

インストール方法を見る

含まれるファイル(1)

  • SKILL.md7.5 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

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());

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

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

日本語の概要は準備中です。原文の説明を表示しています。

KraitDev/skiLL.Md62026年6月8日 更新

When creating or extending an HTTP API for client consumption.

日本語の概要は準備中です。原文の説明を表示しています。

KraitDev/skiLL.Md62026年6月8日 更新

When improving read performance and reducing database load.

日本語の概要は準備中です。原文の説明を表示しています。

KraitDev/skiLL.Md62026年6月8日 更新

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

日本語の概要は準備中です。原文の説明を表示しています。

KraitDev/skiLL.Md62026年6月8日 更新

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

日本語の概要は準備中です。原文の説明を表示しています。

KraitDev/skiLL.Md62026年6月8日 更新

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

日本語の概要は準備中です。原文の説明を表示しています。

KraitDev/skiLL.Md62026年6月8日 更新

KraitDev のスキルをすべて見る

このスキルの問題を報告する