【入門編】ReactにおけるJSXの自動エスケープとdangerouslySetInnerHTMLの危険性 – アプリケーションセキュリティ & 安全な開発防御ガイド

React開発者が知っておくべき「魔法の壁」と「危険な抜け穴」:インジェクション攻撃を防ぐ話

こんにちは。セキュリティの世界で「防波堤」を築く仕事をしている者です。

今日は、Reactを使ってWebアプリを作っている皆さんに、ぜひ知っておいてほしい「セキュリティの基本」をお話しします。「Reactって勝手にセキュリティ対策してくれるんでしょ?」と安心して油断していると、実はそこにこそ、悪意ある攻撃者が狙う「盲点」が隠れているんです。

専門用語を並べるのはやめて、まずは身近な例えから入っていきましょう。

—

1. Reactが守ってくれる「透明な防弾ガラス」

ReactのJSX(

{userContent}

のように書くやつですね)は、実は皆さんが意識しなくても、「自動エスケープ」という強力な盾を張ってくれています。

これを、「家の中の郵便受け」に例えてみましょう。

本来、郵便受け(JSX)は「手紙(データ)」を受け取るためのものです。しかし、そこに悪意のある人間が「手紙のフリをした爆弾(悪意あるスクリプト)」を放り込もうとしたらどうなるでしょう?

Reactという賢い執事は、手紙を受け取るときに「これはただの紙として扱いますよ」と、内容をすべて「文字情報」として無害化してくれます。もし誰かが「爆発しろ!」と書いても、それはただの「爆発しろという文字」として壁に表示されるだけ。これがReactの自動エスケープの正体です。

このおかげで、Reactを使っている限り、基本的には「クロスサイトスクリプティング(XSS)」という、Webサイトを乗っ取られる攻撃から守られているわけです。

—

2. 禁断の扉『dangerouslySetInnerHTML』の危険性

しかし、開発をしていると「どうしてもHTMLタグを含んだ文字列をそのまま表示したい!」という場面にぶつかることがありますよね。CMSから取得したリッチテキストを表示する場合などがそうです。

そこで登場するのが、dangerouslySetInnerHTML というプロパティです。

名前からして物騒でしょう? 名前通り、これは「防弾ガラスにわざと穴を開ける」行為です。

// 危険な例:ユーザーの入力内容をそのままHTMLとして描画する
function DangerousComponent({ rawHtml }) {
// 執事(React)に「この穴から何が入ってきても、そのまま家の中に通してくれ」と命じているのと同じです
return

;
}

このプロパティを使うと、Reactの執事は「これはHTMLタグだから、そのまま実行していいんだな」と判断し、悪意あるスクリプトを「命令」として実行してしまいます。

泥棒が家に入ってくる瞬間

もし、攻撃者が入力欄に以下のような文字列を仕込んだらどうなるでしょうか?

onerror というのは「画像の読み込みに失敗したら実行する」という命令です。Reactの自動エスケープを無効にされたこのページは、攻撃者の命令通りに「実行」してしまいます。これが、Webアプリにおけるインジェクション攻撃の典型的な手口です。

—

3. どうしてもHTMLを表示したいときは?

「じゃあ、HTMLを表示するのは諦めるしかないの?」というと、そうではありません。泥棒が入ってこないように、しっかりとした「防犯対策」を施せばいいのです。

対策:DOMPurifyで「検査」を通す

HTMLをレンダリングする前に、「危険な部品が含まれていないか」をチェックするフィルタを通すのが鉄則です。現場で最も信頼されているライブラリの一つが dompurify です。

import DOMPurify from ‘dompurify’;

function SafeComponent({ rawHtml }) {
// 1. まず、怪しいタグや属性(onerrorなど)を徹底的に取り除く
const cleanHtml = DOMPurify.sanitize(rawHtml);

// 2. 綺麗になったものだけをレンダリングする
return

;
}

これは、郵便受けの裏側に「爆発物を検知するX線スキャナー」を置くようなものです。これを通すことで、onerrorのような悪意ある命令はすべて削除され、安全なHTMLだけが家の中に通されます。

—

4. 最後に:セキュリティは「疑うこと」から始まる

セキュリティは、完璧な魔法ではありません。

  • Reactを信じすぎない(便利な道具ほど、使い方を間違えると危ない)
  • 「dangerously」という名前に敬意を払う(使うときは必ず理由を問い直す)
  • 外部からのデータは常に「泥棒の可能性がある」と疑う

新人の皆さんが現場でコードを書くとき、dangerouslySetInnerHTML という文字を見かけたら、ぜひ一瞬立ち止まってください。「これ、本当に必要かな? 掃除(サニタイズ)はされているかな?」と。

その「立ち止まる心」こそが、あなた自身と、あなたの作ったサービスを守る最高のセキュリティ対策になります。

これからも、一つずつ着実に学んでいきましょう。何か困ったことがあれば、いつでも相談してくださいね。

コメント

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