JavaScriptを使用してWebサイトのコンテンツを動的に変更する際、最も頻繁に利用されるプロパティの一つがinnerHTMLです。
このプロパティは非常に強力で直感的に操作できる反面、使い方を誤ると重大なセキュリティリスクを引き起こす可能性があります。
本記事では、DOM操作の基本であるinnerHTMLの正しい使い方から、現代のWeb開発で必須となるセキュリティ対策、そして代替手段までを詳しく解説します。
innerHTMLとは何か:DOM操作の基本概念
innerHTMLは、指定した要素の中に含まれるHTML要素の構成を、文字列として取得したり変更したりするためのプロパティです。
DOM(Document Object Model)ツリー内の要素にアクセスし、その中身を丸ごと入れ替えることができるため、非常に高い柔軟性を持っています。
innerHTMLの基本的な仕組み
ブラウザは、HTML文書を読み込むと要素をツリー構造として保持します。
innerHTMLプロパティを呼び出すと、ブラウザはその要素の子孫要素をHTMLの文字列としてシリアライズして返します。
逆に、このプロパティに文字列を代入すると、ブラウザはその文字列をHTMLとして解析し、既存のDOM要素を破棄して新しい要素を構築します。
innerTextやtextContentとの決定的な違い
要素の中身を操作するプロパティには、他にもinnerTextやtextContentが存在します。
これらの使い分けを理解することは、予期せぬ不具合や脆弱性を防ぐための第一歩となります。
| プロパティ名 | HTMLの解析 | スタイル(CSS)の影響 | 主な用途 |
|---|---|---|---|
| innerHTML | あり(タグを解釈する) | なし | 要素内にタグを含めた構造を挿入する場合 |
| innerText | なし(単なるテキスト) | あり(非表示要素は取得しない) | 表示されているテキストのみを操作する場合 |
| textContent | なし(単なるテキスト) | なし(全てのテキストを取得) | パフォーマンスを重視し、純粋な文字を扱う場合 |
上記の通り、innerHTMLだけがHTMLタグをタグとして認識してレンダリングするという特徴を持っています。
innerHTMLの基本的な使い方とコード例
それでは、実際のコードを用いてinnerHTMLの使い方を確認していきましょう。
要素の内容を取得する
既存の要素内にどのようなHTMLが含まれているかを取得する方法です。
// id="content"を持つ要素を取得
const element = document.getElementById('content');
// 内容をコンソールに表示
console.log(element.innerHTML);
<p>こんにちは、<strong>ゲスト</strong>さん。</p>
要素の内容を動的に変更する
次に、JavaScript側から要素の内容を書き換える方法を紹介します。
const container = document.querySelector('.container');
// 新しいHTMLをセットする
container.innerHTML = '<h2>新着ニュース</h2><ul><li>記事1</li><li>記事2</li></ul>';
このように、文字列としてHTMLを渡すだけで、一括で複雑な構造を生成できるのがinnerHTMLの最大のメリットです。
innerHTMLに潜む深刻なセキュリティリスク:XSS
非常に便利なinnerHTMLですが、不用意に使用するとクロスサイトスクリプティング(XSS)という脆弱性を生む原因になります。
XSS(クロスサイトスクリプティング)とは
XSSとは、攻撃者が悪意のあるスクリプトをWebページに埋め込み、他のユーザーのブラウザ上で実行させる攻撃手法です。
innerHTMLは受け取った文字列をそのままHTMLとして解析するため、文字列の中に<script>タグや、イベントハンドラが含まれているとそれが実行されてしまいます。
危険なコードの具体例
例えば、ユーザーが入力した名前を表示するだけの簡単な機能を見てみましょう。
// ユーザー入力(本来はフォームなどから取得)
const userInput = "<img src='x' onerror='alert(\"情報を盗みました\")'>";
// innerHTMLで表示する
const displayArea = document.getElementById('user-name');
displayArea.innerHTML = 'ようこそ、' + userInput + 'さん';
この場合、画像タグの読み込み失敗時に発生するonerrorイベントが自動的に発動し、任意のJavaScriptが実行されてしまいます。
これにより、Cookieの盗難やサイトの改ざんといった甚大な被害につながる恐れがあります。
そのため、外部からの入力値をそのままinnerHTMLに渡すことは絶対に避けてください。
innerHTMLを安全に使用するための対策
セキュリティを維持しながらDOMを操作するためには、いくつかの対策手法を適切に選択する必要があります。
1. textContentを優先的に使用する
タグを含める必要がなく、単にテキストを表示するだけであれば、textContentを使用するのが最も安全です。
// タグが含まれていても、そのまま文字列として表示されるため安全
displayArea.textContent = userInput;
textContentは文字列をHTMLとして解析しないため、XSSのリスクを完全に排除できます。
2. サニタイズ(無害化)を行う
どうしてもHTMLタグを許可したい場合は、信頼できるライブラリを使用して「サニタイズ」を行う必要があります。
サニタイズとは、危険なタグや属性を除去し、安全なHTMLのみを残す処理のことです。
2026年現在でも広く利用されているライブラリには「DOMPurify」などがあります。
// DOMPurifyを使用したサニタイズの例
const cleanHTML = DOMPurify.sanitize(userInput);
displayArea.innerHTML = cleanHTML;
3. Trusted Types APIの活用
最新のブラウザ環境では、Trusted Types APIを使用して、安全が確認された文字列以外をDOMに渡せないように制限することも可能です。
これは、コーディングミスによる脆弱性をシステムレベルで防ぐための強力な仕組みです。
innerHTMLのパフォーマンス上の注意点
innerHTMLはセキュリティだけでなく、パフォーマンスの面でも注意が必要です。
再レンダリングのコスト
innerHTMLに値を代入するたびに、ブラウザはその要素内のすべてのDOMノードを破棄し、新しく作り直します。
これは小規模な操作であれば問題になりませんが、大量のループ処理の中で頻繁に行うと、画面のちらつきや動作の重さを引き起こします。
insertAdjacentHTMLの活用
要素の一部だけを追加したい場合は、innerHTML += '...'ではなく、insertAdjacentHTMLを使用する方が効率的です。
const list = document.getElementById('myList');
// 末尾に要素を追加する(既存の要素を再構築しない)
list.insertAdjacentHTML('beforeend', '<li>新しいアイテム</li>');
このメソッドは、既存のDOMツリーを壊さずに特定の位置へ新しいノードを挿入するため、パフォーマンス面で優れています。
DOM要素をプログラムで生成する方法
最も安全かつ堅牢なDOM操作方法は、createElementなどのメソッドを使って一つずつ要素を組み立てる方法です。
const newDiv = document.createElement('div');
newDiv.className = 'info-box';
const text = document.createTextNode('安全にテキストを追加します');
newDiv.appendChild(text);
document.body.appendChild(newDiv);
この手法はコード量が増える傾向にありますが、HTMLの解析ステップを介さないため、XSS攻撃の影響を全く受けないという強力な利点があります。
複雑なUIを構築するモダンな開発現場では、こうした直接的なDOM操作や、フレームワーク(ReactやVue.jsなど)が提供する安全なテンプレート機能が主流となっています。
まとめ
JavaScriptのinnerHTMLは、手軽にコンテンツを書き換えられる非常に便利なプロパティです。
しかし、その背後にはセキュリティリスクやパフォーマンス低下といった課題が隠されています。
安全なWeb開発を行うためには、以下のポイントを常に意識しましょう。
- 単なるテキストの更新には
textContentを使用する。 - 外部からの入力値を扱う際は、必ずサニタイズを行うか
createElementで対応する。 - パフォーマンスが求められる場面では
insertAdjacentHTMLなどを検討する。
これらの基本を守ることで、ユーザーにとって安全で快適なWebアプリケーションを構築することができます。
適切なツールと知識を選び、効果的なDOM操作をマスターしていきましょう。
