【実務・中級編】textContentとinnerHTMLのセキュリティ比較 – HTML実践ガイド

DOM操作の「深淵」を覗く:textContentとinnerHTMLの決定的な境界線

フロントエンド開発の現場において、DOM操作は避けて通れない「日常」です。しかし、その日常の中に潜むわずかな判断ミスが、後に壊滅的なセキュリティ事故を引き起こすことがあります。

特に `textContent` と `innerHTML` の使い分け。これらは単なる文字列出力の違いではありません。ブラウザという名の「エンジン」が裏側でどう動くのか、そしてそこにどんなリスクが潜んでいるのか。今回は、中級エンジニアなら絶対に押さえておくべき、DOM操作のセキュリティ・ベストプラクティスを解説します。

—

1. なぜ「innerHTML」が危険視されるのか

結論から言えば、`innerHTML` はブラウザに対して「HTML文字列を解釈してDOMツリーを構築せよ」と命令するプロパティだからです。

ブラウザのパーサーは、`innerHTML` に文字列が渡されると、それを単なるテキストではなく「構造」として読み解こうとします。もしその文字列の中に `` のような悪意あるスクリプトが混入していたらどうなるか。ブラウザはそれを「危険なコード」とは判断せず、素直に実行してしまいます。これがXSS(クロスサイトスクリプティング)の古典的かつ強力な入り口です。

一方、`textContent` は名前の通り「テキスト内容」です。ブラウザはこれを「HTMLとして解釈せず、ただの文字列として描画する」と判断します。タグが含まれていても、それは単なる記号として画面に表示されるだけで、スクリプトが実行される余地はありません。

—

2. ブラウザが裏側でやっていること

少し技術的な話をしましょう。

  • `innerHTML` の場合:

文字列を受け取ると、ブラウザは「HTML構文解析器(Parser)」を起動します。文字列をトークン化し、DOMノードを生成し、スタイル計算を行い、レイアウトを再計算します。これは非常にコストが高く、かつセキュリティリスクが極大化するプロセスです。

  • `textContent` の場合:

ブラウザは「テキストノード」としてその文字列をそのままセットします。HTMLのタグとしての意味付けは一切無視されます。ブラウザからすれば「ただの長い文字列を一個、この要素の中に入れればいいんだな」という処理で済むため、高速で安全なのです。

—

3. 実践:現場で使える「安全な実装」

では、実務でどう使い分けるべきか。原則は 「デフォルトで `textContent` を使い、どうしてもHTMLが必要なときだけ細心の注意を払う」 です。

以下に、今日から使える実践的なパターンを提示します。

パターンA:安全なテキスト挿入(推奨)

ユーザーが入力した名前などを表示する際は、迷わずこれを使ってください。

const userName = ““; // 悪意のある入力
const displayElement = document.querySelector(‘#user-profile’);

// textContentなら、タグがそのまま文字列として表示されるため安全
displayElement.textContent = `こんにちは、${userName}さん!`;

パターンB:どうしてもHTMLをレンダリングしたい場合

CMSやリッチテキストエディタなど、サーバーから来る「信頼できるHTML」を表示せざるを得ない場合があります。その際は必ず サニタイズ(無害化) を行います。自分で正規表現を書くのはバグの元なので、定評のあるライブラリ(`DOMPurify`など)を使いましょう。

// npm install dompurify
import DOMPurify from ‘dompurify’;

const dirtyHtml = “

正常なコンテンツ

“;

// DOMPurifyで無害化してからinnerHTMLに渡す
const cleanHtml = DOMPurify.sanitize(dirtyHtml);

const contentArea = document.querySelector(‘#content’);
contentArea.innerHTML = cleanHtml;
// 結果:

シェアする
frontendintronationalをフォローする

コメント

タイトルとURLをコピーしました