【ITニュース解説】Implementing Security in Front-End Applications (React)
2025年09月12日に「Dev.to」が公開したITニュース「Implementing Security in Front-End Applications (React)」について初心者にもわかりやすく解説しています。
ITニュース概要
ReactアプリのセキュリティはXSS/CSRF対策が鍵だ。ReactはXSSを自動エスケープで防ぐが、`dangerouslySetInnerHTML`は危険。CSRFはサーバー連携のトークンで防ぐ。CSP・HTML5も安全に使い、フロントエンドを堅牢に開発する。
ITニュース解説
システムエンジニアを目指すにあたり、Webアプリケーションのセキュリティは避けて通れない重要なテーマだ。特に、ユーザーが直接触れるフロントエンドのセキュリティ対策は、アプリケーションの信頼性を保つ上で欠かせない。ここでは、Reactで構築されたフロントエンドアプリケーションにおいて特に気を付けるべき主要なセキュリティ対策について解説する。
まず、一つ目の重要な対策は「クロスサイトスクリプティング(XSS)」の防止だ。XSSとは、攻撃者が悪意のあるスクリプトを信頼されたWebサイトに注入し、そのサイトを閲覧したユーザーのブラウザ上でそのスクリプトを実行させる攻撃である。これにより、ユーザーのセッション情報や個人情報が盗まれたり、ユーザーになりすまして不正な操作が行われたりする可能性がある。例えば、ソーシャルメディアの投稿欄に攻撃者が「<script>alert(document.cookie)</script>」といった悪意のあるコメントを書き込んだとする。もしアプリケーションがこのコメントをそのまま表示してしまうと、そのコメントを見たユーザーのセッションクッキーが攻撃者に露呈してしまう危険性がある。
このXSS攻撃を防ぐためのOWASP(Open Web Application Security Project)の原則は、ユーザーが入力したデータはすべて信頼できないものとして扱うことだ。入力されたデータを画面に表示する前に、必ずサニタイズ(無害化)とエンコード(符号化)を行うことで、コードの注入を防ぐ必要がある。Reactにおいては、この対策がデフォルトで組み込まれているため、開発者は比較的安全にアプリケーションを構築できる。JSX内で波括弧「{}」を使ってコンテンツをレンダリングする際、React DOMは自動的にその中の値をエスケープする。これにより、例えば「<script>」のようなタグはそのままコードとして実行されることなく、単なる文字列として表示されるため、悪意のあるスクリプトの実行を防ぐことができるのだ。
しかし、Reactの強力なセキュリティ機能を意図的に無効にしてしまう「dangerouslySetInnerHTML」という属性を使う場合は、細心の注意が必要だ。この属性を使用すると、Reactの自動エスケープメカニズムを迂回して、指定したHTMLコンテンツをそのままブラウザにレンダリングする。これは、サードパーティのライブラリから取得した整形済みHTMLなど、どうしても生のHTMLをレンダリングする必要がある場合に限定して使用すべきである。もし使うのであれば、そのコンテンツがサーバーサイドでDOMPurifyのようなライブラリを使って徹底的にサニタイズされていることを確認し、安全が保証されたものだけを扱うようにしなければならない。
次に、「クロスサイトリクエストフォージェリ(CSRF)」の防止についても理解しておく必要がある。CSRFは、ユーザーが意図しないうちに、信頼しているサーバーに対して悪意のあるリクエストを送信させる攻撃である。例えば、銀行のウェブサイトで送金処理を行うエンドポイントがあるとしよう。攻撃者は、このエンドポイントの情報を知った上で、偽のウェブサイトを作成し、そこに隠しフォームを仕込む。ユーザーがその偽サイトを訪問した際に、隠しフォームが自動的に銀行の送金エンドポイントに対してリクエストを送信するように仕向けるのだ。もしユーザーがすでに銀行のウェブサイトにログインしている状態であれば、そのリクエストは正規のものとして認証され、意図しない送金が実行されてしまう可能性がある。
CSRF攻撃を防ぐためのOWASPの原則は、CSRFトークンと呼ばれる、予測不能な一意のトークンを使用することである。サーバーは、このトークンを生成し、フォームの隠しフィールドやHTTPヘッダーに含めてクライアントに送信する。クライアントがPOST、PUT、DELETEといった状態を変更するリクエストを送信する際には、このトークンを必ず含め、サーバー側でそのトークンが有効であることを検証することで、不正なリクエストをブロックする。Reactアプリケーションでは、このCSRFトークンの生成と検証自体は主にサーバーサイドで行われる。フロントエンドのReactアプリケーションの役割は、サーバーから送られてきたCSRFトークンを適切に取得し、状態を変更するAPIリクエストの際に、カスタムHTTPヘッダー(例: X-CSRF-Token)に含めてサーバーに送信することだ。AxiosのようなHTTPクライアントライブラリを使用すれば、一度設定すれば以降のリクエストで自動的にトークンを付与するような仕組みを簡単に構築できる。
三つ目のセキュリティ対策は、「コンテンツセキュリティポリシー(CSP)」だ。CSPは、XSSなどのデータ注入攻撃を軽減するための追加のセキュリティ層であり、ブラウザがスクリプト、スタイル、画像などの各種リソースをどのドメインから読み込むことを許可するかを厳密に指定するメカニズムである。例えば、攻撃者が外部の悪意あるスクリプトを注入しようとした場合、CSPが設定されていれば、ブラウザはそのスクリプトの読み込みをブロックするため、実行されることはない。
OWASPの原則では、強力で制限的なCSPを設定し、信頼できるソースをホワイトリスト形式で指定することが推奨されている。このCSPは、サーバーからHTTPレスポンスヘッダーとしてブラウザに送信されるものであるため、Reactアプリケーション自体が直接これを制御するわけではない。しかし、Reactアプリケーションは、このCSPのルール内で動作するように設計されなければならない。もしアプリケーションがサードパーティのCDNからフォントやライブラリを読み込んでいる場合、それらのドメインもCSPで明示的に許可する必要がある。そうしないと、ブラウザがそれらのリソースの読み込みをブロックし、アプリケーションが正しく動作しなくなる可能性がある。
最後に、HTML5の機能が持つセキュリティ上の考慮点にも目を向ける必要がある。最新のブラウザとHTML5は多くの便利な機能を提供する一方で、注意深く扱わないと新たな脆弱性を生み出すことがある。例えば、HTML5の「localStorage」はデータを永続的に保存できる便利な機能だが、セッション情報やトークンといった機密性の高いデータを保存するべきではない。localStorageに保存されたデータはXSS攻撃によって簡単に盗み見られる可能性があるため、機密データは「httpOnly」属性を持つクッキーに保存するなど、より安全な方法を選ぶべきだ。
また、外部のコンテンツを埋め込むための「<iframe>」要素を使用する際には、必ず「sandbox」属性を使用すべきだ。この属性は、埋め込まれたコンテンツが実行できる操作を厳しく制限することで、悪意のあるコンテンツが親ページに影響を与えるのを防ぐ。例えば、「allow-scripts allow-same-origin allow-popups」といった値で、スクリプトの実行、同一オリジンポリシー、ポップアップの許可など、必要最小限の権限のみを与えるように設定できる。
さらに、「target="_blank"」属性を使って新しいタブでリンクを開く場合、「rel="noopener noreferrer"」属性を必ず追加することだ。これは「Tabnabbing(タブナビング)」と呼ばれる攻撃を防ぐための対策である。target="_blank"だけで新しいタブを開くと、開かれた側のタブが元のタブのウィンドウオブジェクト(window.opener)にアクセスし、元のタブのURLを変更するなどの操作を行える可能性がある。noopener属性は、開かれたタブから元のタブへのアクセスをブロックし、noreferrer属性は、新しいタブへのリクエストに元のタブのURL(リファラー)情報が含まれないようにする。
React自体も、デフォルトでいくつかのセキュリティ対策をサポートしている。最も重要なのは、前述したようにJSX内で動的なデータをレンダリングする際の自動エスケープ機能だ。これにより、潜在的に有害な文字が安全なHTMLエンティティに変換され、コードとして実行されるのを防ぐ。また、Reactは仮想DOMを使用し、開発者に直接的なDOM操作を推奨しない。これは、直接的なDOM操作が多くのセキュリティ脆弱性の原因となることが多いことを踏まえると、間接的にセキュリティリスクを低減する効果がある。さらに、コンポーネントベースのアーキテクチャは、関心の分離とカプセル化を促進し、もしあるコンポーネントに脆弱性があったとしても、それがアプリケーション全体に広がるのを防ぐ助けとなる。
これらの対策は、Webアプリケーションを開発する上で基本的ながら非常に重要な知識である。OWASPのチートシートシリーズなど、信頼できる情報源を参照しながら、常に最新のセキュリティ知識を習得し、安全なアプリケーション開発を心がけることが、システムエンジニアとしての責任といえる。