ReactとAngularのセキュアコーディングの実践を比較
2019年10月30日
0 分で読めますSnykの「State of JavaScript frameworks security report 2019」へようこそ。本レポートでは、AngularとReactのプロジェクト全体のセキュリティ状況を取り上げます。
このセクションでは、AngularとReact、それぞれのプロジェクトのセキュリティ状況を見ていきます。セキュアコーディングの規約、組み込みのセキュリティ機能、責任ある脆弱性開示ポリシー、プロジェクト専用のセキュリティドキュメントについて解説します。
次の表では、オープンソースパッケージをベストプラクティスに沿って保守するうえで不可欠なセキュリティ要素をいくつか挙げ、AngularとReactがそれらにどのように対応しているか(または対応していないか)を示します。
項目 | Angular | React |
セキュリティページ | ✅ https://angular.io/guide/security | ❌Reactのウェブサイト(https://reactjs.org)では、APIリファレンスのDOM ElementsセクションにあるdangerouslySetInnerHTML関数の説明を除き、セキュリティガイドラインに言及していません。 |
セキュリティ窓口 | ✅security@angular.io | ❌セキュリティ窓口なし |
責任ある脆弱性開示ポリシー | ✅Googleの社内セキュリティチームが支援し、Googleのセキュリティ理念に基づいています。参考:https://www.google.com/about/appsecurity/ | ❌責任ある脆弱性開示ポリシーなし |
脆弱なプロジェクトの例 | ✅https://angular.io/generated/live-examples/security/stackblitz. html | ❌脆弱なプロジェクトの例への言及なし |
組み込みのサニタイズ機能 | ✅DomSanitizerは、信頼できない値をサニタイズする組み込み機能を提供します。参考:https://angular.io/api/platform-browser/DomSanitizer#sanitize | ❌悪意のある可能性がある入力のサニタイズは、DOMPurifyなどのサードパーティライブラリを使って実装するかどうか、ユーザーの判断に委ねられています。参考:https://github.com/cure53/DOMPurify |
コンテンツセキュリティポリシー(CSP) | ✅Angular v1.xディレクティブのCSP互換性。参考:https://docs.angularjs.org/api/ng/directive/ngCsp | 🔘Reactには該当しません |
✅AngularのHttpClientサービスでCSRFを標準サポート。参考:https://angular.io/guide/http および https://docs.angularjs.org/api/ng/service/$http | 🔘ビューライブラリであるReactには該当しません。カスタムコードやコミュニティモジュールを使って、開発者が対応する必要があります。 |
Angularのセキュアコーディングの実践
Angular v2以降は、単方向データバインディングなど、Angular v1とはアーキテクチャが大きく異なります。また、v2以降では、Angular v1のセキュリティ脆弱性の多くにつながっていた、watcherによる自動データ補間やその他の手法も廃止されています。
Ahead of Time(AoT)コンパイルは、Angularテンプレート式へのインジェクションなどの問題を軽減し、実行時ではなくビルド時にセキュリティを確保します。ただし、クライアント側でテンプレートを動的に補間すると、Angularコードインジェクションによる脆弱性の余地が残ります。Angularはベストプラクティスのドキュメントで、この動的な補間を強く避けるよう明示しています。Angularのドキュメントにおいても、ベストプラクティスとして明確に非推奨とされています。
クロスサイトスクリプティングの脆弱性を軽減するため、Angularはデフォルトでコンテキストに応じた出力エンコーディング、または悪意のあるコードのサニタイズを行います。また、開発者がその影響を理解したうえで意識的に使用する場合、メソッドの命名規則によって危険性がより明確に伝わります。これは、Angular v1.xなどの旧バージョンとは異なる点です。
bypassSecurityTrustHtml(value)やbypassSecurityTrustUrl()のようなメソッド名は、DOMへのデータ挿入にこれらを使用する危険性を明確に示しています。さらにAngularには、値を明示的にサニタイズする組み込みのDomSanitizerが用意されています。
Reactのセキュアコーディングの実践
Reactは、DOM要素の作成時にほぼすべてのデータ値をデフォルトでエンコードします。HTMLコンテンツをDOMに挿入するための回避策として、Reactには、その危険性を明確に伝える名前の関数dangerouslySetInnerHTML()が用意されています。
Reactのセキュリティモデルの対象外となり、ユーザー側で対応する必要があるケースには、次のようなものがあります。
ユーザー入力をhref属性値のソースとして使うHTMLアンカー(リンク)要素の作成。これは主に、最近リリースされたReact v16.9より前のバージョンに該当します。React v16.9では、javascript:ベースのURLがhref属性値に指定されるケースや、フォームのaction、iFrameのソースなど、他のコンテキストでの問題が軽減されています。
ユーザー入力からのReactコンポーネントの作成
Reactのサーバーサイドレンダリングでは、悪意のあるユーザー入力を適切にエンコードまたはサニタイズせず、そのままJavaScriptのコンテキストに挿入すると、XSSの脆弱性が生じる可能性があります。
HTTPセキュリティ
バージョン1.2以降、Angular v1.xのリリースブランチでは、式の補間にeval()とFunction()を使用するために必要となる、コンテンツセキュリティポリシー(CSP)との互換性が導入されています。
クロスサイトリクエストフォージェリ(CSRF)によって、ウェブアプリケーションはリクエストの送信元を信頼してしまう可能性があります。新しいAngularのバージョンでは、HTTPクライアントに@angular/common/ httpモジュールを通じたCSRF対策が組み込まれています。Angular v1.xでは、$httpプロバイダーを通じて同様の機能を利用できます。
Angularとは異なり、ReactにはHTTPクライアントが含まれていないため、CSRF対策を標準では提供できません。Reactは最小限のビューライブラリを目指しているため、カスタムコードやコミュニティが提供するモジュールを使って、この問題に開発者が対処する必要があります。
デジタル形式でレポートの完全版をダウンロードすることを強くおすすめしますが、以下の一般的なセクションはブログ記事としても公開しています。



