ReactのXSS:dangerouslySetInnerHTMLとサードパーティスクリプト
ReactのデフォルトのエスケープがXSSを防ぐ仕組み、dangerouslySetInnerHTMLが危険になる場面、サードパーティスクリプトがリスクをもたらす仕組みを理解します。
「ReactのXSS:dangerouslySetInnerHTMLとサードパーティスクリプト」はCoddyKit上の無料React Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。
React に組み込まれた XSS 防御
React は JSX を介してレンダリングされるすべての値を DOM に挿入する前に自動的にエスケープします。JSX で {userInput} と記述すると、React は textContent の代入に相当する処理を行います。値は HTML ではなく、常にテキストとして扱われます。これにより、React アプリケーションでは大半の XSS 攻撃がデフォルトで防止されます。
dangerouslySetInnerHTML の動作
dangerouslySetInnerHTML={{ __html: htmlString }} は、自動エスケープを回避する React のエスケープハッチです。この名前は意図的に警告を促すものです。HTML 文字列の安全性について、自分で責任を負うことを示しています。React は innerHTML を直接設定するため、スクリプトやイベントハンドラーを含むあらゆる HTML が実行されます。
正当な用途
TipTap や Quill のようなリッチテキストエディター、HTML を保存する CMS、Markdown から HTML へのコンバーターに由来する HTML をレンダリングする場合は、dangerouslySetInnerHTML が本当に必要になります。これらのソースは、エスケープされたテキストではなく HTML としてレンダリングする必要がある、実際の HTML マークアップを生成します。
攻撃経路
HTML 文字列に <script>stealCookies()</script> や <img src=x onerror="stealData()"> が含まれている場合、それを innerHTML として設定すると攻撃者のコードが実行されます。サニタイズせずにユーザーが提供したコンテンツを直接 dangerouslySetInnerHTML に渡すと、重大な XSS 脆弱性になります。
DOMPurify:標準のサニタイザー
DOMPurify は、ブラウザ向けの業界標準 HTML サニタイザーです。HTML 文字列をサンドボックス化されたコンテキストで解析し、危険な要素や属性(script タグ、on-event ハンドラー、javascript: URL)を削除して、安全な HTML 文字列を返します。dangerouslySetInnerHTML に渡す前に、DOMPurify.sanitize(dirtyHtml) を使用します。
サードパーティスクリプトのリスク
サードパーティスクリプト(分析、チャットウィジェット、広告ネットワーク)は、アプリケーションの JavaScript と同じ権限で実行されます。侵害された、または悪意のあるサードパーティスクリプトは、document.cookie を読み取り、localStorage にアクセスし、フォーム入力を読み取り、外部サーバーにリクエストを送信できます。しかも、ユーザーにはその兆候が一切示されません。
防御層としての Content Security Policy
Content Security Policy は、実行を許可するスクリプトを宣言する HTTP ヘッダーです。XSS ペイロードが DOM に注入された場合でも、適切に設定された CSP は、インラインスクリプトを制限し、ホワイトリストに登録されたスクリプトソースだけを許可することで、その実行を阻止できます。CSP は入力サニタイズに続く第2の防御層です。
npm を介したサプライチェーン攻撃
npm パッケージは、実際の XSS 攻撃経路になり得ます。依存関係に、環境変数やユーザーデータを外部に送信する悪意のあるコードが含まれている可能性があります。2022年の node-ipc インシデントと、2021年の ua-parser-js の侵害は、広く使われているパッケージでも乗っ取られ、悪意のあるコードを仕込まれる可能性があることを示しました。npm audit で依存関係を監査し、ロックファイルを使用してください。
攻撃者が XSS で行うこと
成功した XSS 攻撃によって、攻撃者はユーザーの sessionStorage にある JWT トークンを盗み(攻撃者が管理するサーバーに送信する)、認証済みユーザーとして操作を実行し(ユーザーのセッションを使った API 呼び出し)、DOM を変更してフィッシングコンテンツを表示したり、アプリケーションでユーザーが入力するすべてのキー入力を記録したりできます。
Trusted Types API
Trusted Types ブラウザ API は、すべての DOM シンク(innerHTML、eval、script.src)が生の文字列ではなく、特別な型付きオブジェクトを受け取るようにします。これにより、文字列ベースの XSS ペイロードがプラットフォームレベルで DOM に到達することを防ぎます。React は Trusted Types との互換性に向けて対応を進めており、CSP でそれを強制できます。
CMS コンテンツの安全なパターン
CMS の HTML をレンダリングする安全なパターンは、HTML を取得し、安全なタグと属性の許可リストを指定して DOMPurify.sanitize() に通し、その後 dangerouslySetInnerHTML={{ __html: cleanHtml }} でレンダリングすることです。CMS を信頼している場合でも、サニタイズの手順を決して省略しないでください。CMS のデータベース自体が侵害される可能性があるためです。
DOMPurify の役割
DOMPurify.sanitize(htmlString) を呼び出すと、DOMPurify は何を行いますか?
レッスンのまとめ
React は JSX の値を自動的にエスケープし、大半の XSS を防止します。dangerouslySetInnerHTML は正当な HTML レンダリングのためにこの処理を回避しますが、必ず先に DOMPurify で入力をサニタイズしてください。サードパーティスクリプトや侵害された npm パッケージは、サプライチェーンを通じた XSS の攻撃経路になります。Content Security Policy は第2の防御層を提供します。XSS に成功すると、トークンの窃取、ユーザーへのなりすまし、フィッシングが可能になります。
よくある質問
「ReactのXSS:dangerouslySetInnerHTMLとサードパーティスクリプト」レッスンは無料ですか?
はい。「ReactのXSS:dangerouslySetInnerHTMLとサードパーティスクリプト」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。
「ReactのXSS:dangerouslySetInnerHTMLとサードパーティスクリプト」で何を学びますか?
ReactのデフォルトのエスケープがXSSを防ぐ仕組み、dangerouslySetInnerHTMLが危険になる場面、サードパーティスクリプトがリスクをもたらす仕組みを理解します。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
React Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「ReactのXSS:dangerouslySetInnerHTMLとサードパーティスクリプト」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このReact Academyレッスンでコードを書いて実行できますか?
はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- ReactのXSS:dangerouslySetInnerHTMLとサードパーティスクリプト
- ReactとAPI構成におけるCSRF対策
- ReactアプリのContent Security Policy
- シークレット管理と環境変数