コンテンツにスキップ
svelte-vitals
日本語
Esc
移動開く⌘Jプレビュー
このページの内容

security/raw-html · 生 HTML のレンダリング

{@html} は HTML をエスケープせずに描画します。値は必ずサニタイズしてください。

重大度: warning · カテゴリ: security

チェック内容

コンポーネント内のすべての {@html …} を検出します(CLI による src/**/*.svelte の静的解析)。

なぜ重要か

{@html} は値をエスケープせずに HTML として描画します。値にユーザー入力が混ざり得るのにサニタイズされていなければ、クロスサイトスクリプティング(XSS)の経路になります。静的解析ではサニタイズの有無を証明できないため、すべての使用箇所をレビュー対象として提示します。

修正方法

描画前にサニタイズするか、テキスト/マークアップとして描画します。

<script>
  import DOMPurify from 'dompurify';
  let { html } = $props();
</script>

<!-- svelte-vitals-disable-next-line security/raw-html -->
{@html DOMPurify.sanitize(html)}

サニタイズしても {@html} はソースに残るため、この検出は設計上ずっと発火し続けます。ルールの不具合ではなく、検出を消せる「修正」は存在しません。呼び出しをレビューし、値がサニタイズ済みであることを確認したら、上記のように inline directive で抑制してください({@html} の直前の行に置く必要があります)。

汎用の HTML サニタイザーも、HTML ではないペイロードには不向きなツールです。よくある例が JSON-LD です。Svelte はマークアップ内の <script> タグの中にある {...} 式を評価せず、そのままリテラルテキストとして出力するため、動的な JSON-LD ブロックは {@html} で挿入するしかありません。そして HTML 用のサニタイザーは、そこでは見当違いの検査しかできません。この挿入を安全にするのは script 安全なシリアライズです。<\u003c にエスケープし(例: JSON.stringify(data).replace(/</g, '\\u003c'))、文字列値に含まれる </script> がタグを途中で閉じて以降がマークアップとして解釈されないようにします。データを「信頼できる」とレビューするだけでは不十分です。正当なデータにも </script> は含まれ得ます。値がこの形でシリアライズされている(または純粋なリテラルでレビュー済みの JSON である)ことを確認できたら、HTML サニタイザーを通すのではなく、この検出を抑制してください。

モードによる違い

ありません。このルールが読むのは同じ .svelte / .ts のソースファイルなので、CLI、Vite プラグインのビルド、ライブダッシュボードの静的ベースラインのいずれでも結果は同一で、レンダリング済み HTML の解析で再評価されることもありません。--route で実行範囲を絞ると、このルールは動きません。コンポーネントスコープのルールには、検出を紐づけるルートが無いためです。

無効化

個別に抑制するには、対象行の直前に <!-- svelte-vitals-disable-next-line security/raw-html --> を置きます。ルールごと無効化するには、次のように設定します。

export default {
  rules: {
    'security/raw-html': 'off'
  }
};