mcpField
X
xss-prevention

xss-prevention

github.com/secondskyセキュリティ240301 回インストール5 週間前に更新
リポジトリ

xss-prevention について

Web 開発者向けの XSS 対策スキルです。入力のサニタイズ、文脈に応じた出力エンコード、CSP、安全な DOM API を扱い、ユーザーコンテンツや動的 HTML に適用できます。

主な機能

  1. 01文脈に応じた出力エンコード
  2. 02許可リストによる HTML サニタイズ
  3. 03CSP ヘッダーの設定
  4. 04安全な DOM API の利用
  5. 05URL プロトコルの検証

活用シーン

  1. 01ユーザー生成コンテンツの安全な表示
  2. 02コメントやリッチテキストエディターの保護
  3. 03検索パラメーターと動的 HTML の処理
  4. 04URL とスクリプト注入リスクの確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/secondsky/claude-skills --skill xss-prevention

インストール後、Claude Code で/xss-preventionを入力して読み込まれたか確認します。

同梱ファイルreferences/nodejs-advanced.mdreferences/python-sanitization.md

詳細

XSS の防止

概要

入力のサニタイズ、出力のエンコード、Content Security Policy ヘッダー、安全なコーディング手法を通じて、包括的なクロスサイトスクリプティング攻撃対策を実装します。

使用する場面

  • ユーザー生成コンテンツの表示
  • リッチテキストエディター
  • コメントシステム
  • 検索機能
  • 動的な HTML の生成
  • テンプレートのレンダリング

XSS 攻撃の種類

種類攻撃経路防御策
反射型URL パラメーター出力エンコード
格納型データベースのコンテンツ入力のサニタイズ
DOM ベースクライアント側の JS安全な DOM API
ミューテーションHTML パーサーの癖厳格なサニタイズ

出力エンコード(Node.js)

function encodeHTML(str) {
  return str
    .replace(/&/g, '&')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#x27;');
}

function encodeForAttribute(str) {
  return str.replace(/[^\w.-]/g, char =>
    `&#x${char.charCodeAt(0).toString(16)};`
  );
}

// Usage in templates
app.get('/profile', (req, res) => {
  const username = encodeHTML(req.query.name);
  res.send(`<h1>Welcome, ${username}</h1>`);
});

DOMPurify によるサニタイズ

import DOMPurify from 'dompurify';

const config = {
  ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'br'],
  ALLOWED_ATTR: ['href', 'title'],
  ALLOW_DATA_ATTR: false
};

function sanitizeHTML(dirty) {
  return DOMPurify.sanitize(dirty, config);
}

// React component
function RichContent({ html }) {
  return (
    <div dangerouslySetInnerHTML={{ __html: sanitizeHTML(html) }} />
  );
}

Content Security Policy

// Express middleware
app.use((req, res, next) => {
  const nonce = crypto.randomBytes(16).toString('base64');
  res.locals.nonce = nonce;

  res.setHeader('Content-Security-Policy', [
    "default-src 'self'",
    `script-src 'self' 'nonce-${nonce}'`,
    "style-src 'self' 'unsafe-inline'",
    "img-src 'self' data: https:",
    "connect-src 'self' https://api.example.com",
    "frame-ancestors 'none'",
    "base-uri 'self'",
    "form-action 'self'"
  ].join('; '));

  next();
});

安全な DOM API

❌ ユーザーが制御する入力に対して、以下の操作は絶対に行わないでください。これらは XSS のシンクであり、信頼できないデータを使って安全に呼び出す方法はありません。

  • 入力を element.innerHTML / element.outerHTML に代入する
  • 入力を eval() に渡す
  • 入力を document.write() に渡す
  • 文字列として setTimeout / setInterval に渡す
  • インラインイベントハンドラーに挿入する(例:onclick="...")
// SAFE — use these instead
element.textContent = userInput;      // Escaped automatically
element.setAttribute('data-id', id);  // Safe for attributes
document.createTextNode(userInput);   // Creates safe text node

上記の安全なパターン(textContent、setAttribute による属性のエスケープ、DOMPurify.sanitize)だけが、DOM 内でユーザー入力を処理する正しい方法です。

URL の検証

function isSafeURL(url) {
  try {
    const parsed = new URL(url);
    return ['http:', 'https:'].includes(parsed.protocol);
  } catch {
    return false;
  }
}

// Usage
const href = isSafeURL(userURL) ? userURL : '#';

コンテキストに応じたエンコード

コンテキストごとに適切なエンコード方法は異なります。

  • HTML エンティティエンコード:テキストコンテンツに最も安全な方法
  • 属性のエンコード:HTML 属性向け
  • JavaScript のエスケープ:スクリプトのコンテキスト向け
  • URL エンコード:URL パラメーター向け
  • CSS のエスケープ:スタイルシートのコンテキスト向け

データがレンダリングされるコンテキストに応じて、常に出力をエンコードしてください。

その他の実装

以下については、references/python-sanitization.md を参照してください。

  • Python の bleach ライブラリの使い方
  • Flask/Django のテンプレートエスケープ
  • サーバー側の検証パターン

以下については、references/nodejs-advanced.md を参照してください。

  • すべてのメソッドを備えた XSSPrevention クラスの完全な実装
  • Express ミドルウェア(xssProtection)
  • React コンポーネント(SafeText、SafeHTML、SafeLink、useSanitizedInput)
  • Helmet の CSP 設定

ベストプラクティス

✅ 推奨事項:

  • デフォルトで出力をエンコードする
  • 自動エスケープ機能のあるテンプレートエンジンを使用する
  • CSP ヘッダーを実装する
  • 許可リストを使ってリッチコンテンツをサニタイズする
  • プロトコルの許可リストを使って URL を検証する
  • HTTPOnly Cookie を使用する
  • 定期的にセキュリティテストを実施する
  • セキュリティに優れたフレームワークを活用する

❌ 禁止事項:

  • ユーザー入力を信頼する
  • 安全でない関数(eval、innerHTML)を使用する
  • 利便性のためにセキュリティ機能を無効にする
  • クライアント側の検証だけに頼る
  • 許可リストではなく拒否リストを使用する
  • コンテキストに応じたエンコードを省略する
  • 任意のスクリプト実行を許可する

セキュリティチェックリスト

  • すべての出力をコンテキスト(HTML、属性、JS)に応じてエンコードする
  • 許可リスト(拒否リストではなく)を使って HTML をサニタイズする
  • 厳格な CSP ヘッダーを実装する
  • セッションには HTTPOnly Cookie を使用する
  • URL を検証してサニタイズする
  • ユーザーコンテンツに innerHTML を使用しない
  • 定期的にセキュリティテストを実施する

リソース

コメント