タグ: React

  • サニタイズ

    安全でない可能性のあるHTMLコンテンツを、XSS(クロスサイトスクリプティング)攻撃などのセキュリティ上の脅威から保護するためにサニタイズ(無害化)してから表示する例を示す。

    環境

    vite@7.1.11
    react@19.2.0
    dompurify@3.3.0

    リポジトリはこちら

    コードの主要な機能と説明

    App.jsx

    import { useState } from 'react';
    import { useSanitizedHtml } from './hooks/useSanitizedHtml'; // 作成したカスタムフックをインポート
    import './App.css';
    
    function App() {
      // ユーザーや外部APIから取得された、サニタイズされていない可能性のあるHTML
      const [userInput] = useState(`
        <p>こちらは<strong>安全なコンテンツ</strong>です。</p>
        <img src="x" onerror="alert('XSS Attack!')"> <a href="javascript:void(0)">クリックしても安全</a>
        <script>console.log('Ignore this');</script> `);
    
      // カスタムフックを使ってHTMLをサニタイズ
      const safeHtml = useSanitizedHtml(userInput);
    
      return (
        <div className="content-container">
          <h2>DOMPurifyでサニタイズしたHTMLの表示</h2>
          {/* <div dangerouslySetInnerHTML={{__html: safeHtml}} /> */}
          <div dangerouslySetInnerHTML={{__html: userInput}} />
          <p>`onerror`属性や`script`タグは除去されています。</p>
        </div>
      );
    }
    
    export default App
    

    userInput
    サニタイズ前のHTMLコンテンツ(Dirty HTML)が格納されています。

    onerror="alert('XSS Attack!')"
    イベントハンドラを使ったXSSの例です。

    <script>...</script>
    スクリプトタグを使ったXSSの例です。

    const safeHtml = useSanitizedHtml(userInput);
    定義した userInput をインポートした useSanitizedHtml カスタムフックに渡し、サニタイズ処理を実行させる。処理後の安全なHTML文字列(Clean HTML)が safeHtml 変数に格納される。この変数の内容には、XSSにつながる要素や属性は含まれない。

    useSanitizedHtml.js

    import DOMPurify from 'dompurify';
    
    /**
     * 危険なHTML文字列を受け取り、DOMPurifyでサニタイズされた安全なHTMLを返す。
     * @param {string} dirtyHtml サニタイズ前のHTML文字列
     * @returns {string} サニタイズ後の安全なHTML文字列
     */
    export const useSanitizedHtml = (dirtyHtml) => {
    
      if (!dirtyHtml) return '';
    
      const cleanHtml = DOMPurify.sanitize(dirtyHtml);// DOMPurifyでHTMLをサニタイズ。オプションで許可するタグや属性などを指定できる(例: {ALLOWED_TAGS: ['b', 'i', 'a']})
    
      return cleanHtml;
    };

    if (!dirtyHtml) return '';
    入力が存在しない(null や空文字列など)場合は、そのまま空文字列を返す。

    const cleanHtml = DOMPurify.sanitize(dirtyHtml);
    受け取った dirtyHtmlDOMPurify.sanitize() メソッドに渡す。このメソッドは、<script> タグや onerror などの危険な属性を検知し、これらを完全に除去または無効化して無害なHTMLのみを残す。

    return cleanHtml;
    サニタイズされた安全なHTML文字列が呼び出し元(例: App.jsx)に返される。