Angularセキュリティのベストプラクティス

太陽がなんとなく春めいてきましたね。
そして、なんとなく頭も重く、目も痒いこの季節。。。そう、花粉。
何か始めるにあたって良さそうな季節だったのですが、
1月から始まる予定だったコーディングブートキャンプが中止となりました。。。:sweat_smile:
残念な気持ちと、若干、ホットする気持ちもあり、、、

今回は、こちらから。

https://snyk.io/blog/angular-security-best-practices/
 
フレームワークは、数多くありますが、今回はAngularのコーディングのセキュリティ対策。
xssの防御、プロジェクトのスキャンといったベースの知識はAngularに関わらず、役立ちそうです。

#Angularセキュリティのベストプラクティス

Liran Tal（リラン・タル）Natalia Venditto（ナタリー・ベンディット）

2020年8月10日
前回は、[AngularJSセキュリティの基礎知識のチートシート](https://snyk.io/blog/angularjs-security/)をご紹介しました。今回は、最新のAngularセキュリティのベストプラクティスをご紹介します。
[AngularSecurityのベストプラクティスに関するチートシートはこちらからダウンロード](https://snyk.io/wp-content/uploads/Angular-Security-Best-Practices-1.pdf)できます。
 
 
 
###Angularセキュリティ ベストプラクティス6　
1.「Angular Way」でXSSからから身を守る
2. innerHTMLを注意して使用する
3. ユーザーの入力を連結して生成したテンプレートを使用しない
4. ネイティブDOM APIを使ってHTML要素を操作しない
5. サーバーサイドのテンプレートでテンプレートエンジンを使用しない
6. Angularプロジェクトをスキャンして、セキュリティの脆弱性をもたらすコンポーネントを探す



##1.「Angular Way」でXSSから守る
#####Angularセキュリティのベストプラクティス＃1：補間（{{}}）を使用して、潜在的に危険な文字を安全にエンコードし、テンプレート式内の信頼できないHTMLやCSS式をエスケープします。 
 
Angularは、ReactやVue.jsと同様に、ブラウザで文字列補間を処理する方法において、セキュリティ・バイ・デフォルトのアプローチを採用しています。デフォルトでは、すべてのデータは安全で信頼できないものとして扱われます。したがって、これらのライブラリやその他の最新のビューライブラリは、HTMLコンテキスト内のすべてのテキストに対してデフォルトで出力エンコーディングを実行するというベストプラクティスに従っています。
[AngularJS Securityのベストプラクティス](https://snyk.io/blog/angularjs-security/)について以前のブログ記事で詳しく説明しましたが、Webアプリケーションを危険にさらし、Webアプリケーションを[クロスサイトスクリプティング（XSS）の脆弱性](https://snyk.io/learn/cross-site-scripting/)にさらす可能性のある悪意のあるユーザー入力を回避するために、ビルトインの中括弧による文字列補間を使用して「Angular Way」に従うことを強く推奨します。
 
##2.innerHTMLを注意して使用する
#####Angularセキュリティのベストプラクティス＃2：HTMLをコンポーネントに動的に追加する必要がある場合は、その生成を`[innerHTML]`にバインドします。これにより、データはそのコンテキストでHTMLとして解釈され、サニタイズされ、安全でないタグをすべて削除してサニタイズされるため、悪意のあるクロスサイトスクリプティングコードの実行を防ぐことができます。サニタイズとエンコードは同じではないことに注意してください。

####サニタイズと出力エンコーディングの違いは何ですか？

出力エンコーディングでは、文字列は特定のHTMLタグにマッピングできるテキスト表現に置き換えられます。たとえば、`script`などの入力が解析された場合、Angularは、セキュリティのベストプラクティスを実装する他の多くのライブラリやフレームワークの標準である、特殊な角括弧表記をエンコードして、そのテキストを表示することを選択できます。そのために、[HTMLエンティティ](https://developer.mozilla.org/en-US/docs/Glossary/Entity)エンコーディングと呼ばれるマッピングを行い、次のテキスト:`script`をDOMに書き込みます。次に、ブラウザはコンテキストを解釈し、`script`タグを出力します。

サニタイズやフィルタリングは、出力エンコーディングとは異なり、安全でない文字を検出し、DOMに書き込まれるテキストから取り除くという、より積極的なアプローチをとることが評価されています。
コンテキストは、出力エンコーディングとサニタイズの決定要因となり、アクションを適切に実行する方法に直接影響を与えます。

セキュリティコンテキストの詳細については、[Angularのドキュメント](https://angular.io/guide/security)を参照してください。

>Angularでは、以下のセキュリティコンテキストを定義しています。
* HTMLは、値をHTMLとして解釈する場合、たとえば、innerHtmlにバインドする場合に使用されます。
* StyleはCSSをstyleプロパティにバインドするときに使用されます。
* URLは、`<a href>`などのURLプロパティに使用されます。
* リソースURLは、コードとして読み込まれて実行されるURLで、例えば、`<script src>`の中にあります。 


フィルタリングされないURLの特別な扱いに注意してください。
</font>


##3.ユーザーの入力を連結して生成したテンプレートを使用しない

#####Angularセキュリティのベストプラクティス＃3：ユーザーが入力した可能性のある文字列をテンプレートに連結してはいけません。

Angularアプリケーションでは、文字列補間や推奨されるコンポーネント構成を適切に使用せず、テンプレートを連結する必要があるユースケースは、あったとしても最小限であるべきです。もし、コードベースでこのような悪い習慣に遭遇した場合は、与えられた入力を可能な限りサニタイズまたはリファクタリングすることをお勧めします。

ここでは、どのようなことに注意し、回避すべきかの例を示します。

<img src="https://snyk.io/wp-content/uploads/image4-5.png">
Angular Securityのベストプラクティス：ユーザー入力を連結して生成されたテンプレートを使用しないでください
 
特に、20行目の文字列とテンプレートの連結に注意してください。`potentialUserInput`の値は、出所が不明または信頼できない悪意のある表現である可能性があります。これは悪い習慣の一例であり、注意が必要です。
以下は、[Angularプレイグラウンド](https://stackblitz.com/edit/angular-ur2nt1?file=src%2Fapp%2Fhero-job-ad.component.ts)で試すことができるより完全な図であり、テンプレートに連結された場合にユーザー入力が安全に処理されない方法を示しています。

<img src="https://snyk.io/wp-content/uploads/image1-3.png">
Angular Securityのベストプラクティスの実践：ユーザー入力を連結して生成されたテンプレートは絶対に使用しないでください
 
この点で、[Angularセキュリティガイド](https://angular.io/guide/security#offline-template-compiler)の公式推奨事項は次のように述べています。

>「ユーザー入力とテンプレートを連結してテンプレートソースコードを生成しないでください。これらの脆弱性を防ぐには、オフラインテンプレートコンパイラ（テンプレートインジェクションとも呼ばれます）を使用してください。」
–Angularセキュリティガイド
 
 
Angularは、Ahead ofTimeコンパイラを使用してテンプレートをオフラインでコンパイルすることを推奨しています。これにより、膨大な数のテンプレート・インジェクションの脆弱性を完全に回避することができます。
 
```console
ng build --aot
ng serve --aot
```

なお、最新のAngular-Angular v9以降のバージョンでIvyを使ってコンパイルすると、事前コンパイルがデフォルトでtrueに設定され、テンプレート・インジェクションを防ぐことができます。

```console
{
  "projects": {
    "my-existing-project": {
      "architect": {
        "build": {
          "options": {
            ...
            "aot": true,
          }
        }
      }
    }
  }
}
```

##4.ネイティブDOM APIを使ってHTML要素とやりとりをしない

#####Angularセキュリティのベストプラクティス＃4：ネイティブDOMAPIを使用してページ上のHTML要素を操作しないでください。

直接的なDOM操作を避け、代わりにAngularのテンプレート・メカニズムやAngular自身のAPIを使ってDOMを操作しましょう。一般的なガイドラインとして、次のことは避けてください。

* `node.appendChild();` 
* `document`オブジェクトメソッドを使用してページを操作する
* jQueryAPIの使用

AngularのネイティブAPIには、私たちが忠告しているのと同じタイプの直接的なDOM操作を可能にするものがあります。たとえばElementRef APIなどです。Angular の ElementRef は、DOM ノードに直接アクセスし、その時点で操作を行うために使用されると、セキュリティ上の問題が発生します。
このように、Angular の一連の API 以外でのやり取りは、セキュリティの脆弱性につながる可能性があります。
 
##5.サーバーサイドのテンプレートでテンプレートエンジンを使用しないでください
#####Angularセキュリティのベストプラクティス#5：サードパーティのテンプレートエンジンで、Angularのサーバーサイドレンダリングアプリケーションにテンプレートデータを作成または追加することは避けてください。
Node.jsを使用してWebアプリケーションを構築したことがある方は、
EJS、Pug、[Handlebars](https://handlebarsjs.com/)、またはそれらの代替の1つなどのテンプレートエンジンを使用したことがあると思います。これらは、ビューレイヤーのサーバー第どでレンダリングされたテンプレートを管理するために使用され、パーシャルまたはレイアウトコンポジット、およびビューを動的に生成するのに役立つその他の種類の機能が含まれる場合があります。 
しかし、これらのテンプレートエンジンの仕組みをAngularのサーバーサイドレンダリングアプリケーションの構成で実装すると、テンプレートに悪意のあるコードが注入される可能性があります。これは、注入されたデータがAngular APIのスコープの外部にあり、サニタイズできないために起こるもので、テンプレートの文字列連結と同様のリスクがあります。

##6. Angularプロジェクトをスキャンして、セキュリティの脆弱性をもたらすコンポーネントを探す
#####Angularセキュリティのベストプラクティス＃6：セキュリティの脆弱性についてAngularプロジェクトのオープンソースの依存関係とAngularコンポーネントを常にスキャンしてください。[SnykプラットフォームまたはCLIを無料で使用してセキュリティの脆弱性を見つけ、修正し、監視](https://app.snyk.io/login)を行いましょう。

Angularとそのエコシステムであるモジュールやコンポーネントのようなサードパーティのライブラリを使用する際には、次の点に注意する必要があります：コアのAngularライブラリに影響を与えるセキュリティ脆弱性と、プロジェクトでインポートして使用しているサードパーティのAngularモジュールに存在するセキュリティ脆弱性があります
 
[既知の脆弱性を持つコンポーネントの使用](https://owasp.org/www-project-top-ten/)は、実際には[OWASPトップ10](https://snyk.io/learn/owasp-top-10-vulnerabilities/)のWebセキュリティリスクとして文書化されており、注意する必要があります。
実際、次の図は、既知のセキュリティ脆弱性を持つAngularモジュールのリストを示しています。たとえば、`npm install`または`npm audit`を実行するとフラグが立てられるモジュールです。実際、[JavaScriptフレームワークのセキュリティレポート](https://snyk.io/blog/javascript-frameworks-security-report-2019/)から引用した画像にあるように、これらの中には、年間数百万回のダウンロードを獲得しているにもかかわらず、今日まで**セキュリティ修正が行われていない**ものがあります。
<img src="https://snyk.io/wp-content/uploads/image2-5.png">
Angularセキュリティ–間接的な依存関係のリスク

###AngularWebアプリケーションのセキュリティ
あなたが`npm audit`を使用しているなら、最初のステップとしては良いことです！
 
ただし、npmの監査機能を使用している場合でも、低減すべきセキュリティ上の懸念があります。

＊*今のところプロジェクトのすべてのセキュリティの脆弱性を解決したかもしれませんが、それらのAngularモジュールの1つに新しい脆弱性が発見された場合はどうでしょうか。それがVercel、NetlifyなどにデプロイされたAngularアプリケーションの1つに影響があるかどうかを知ることができるでしょうか。
* もう1つの懸念は`npm audit`は、公式のCVEを持つ既知の脆弱性のみを追跡しているということです。[SnykはAngular関連モジュールの23を超えるセキュリティ脆弱性を追跡](https://snyk.io/blog/angular-vs-react-security-bakeoff-2019/)していますが、npm監査のレポートではこれらの報告はされません。
 
#####Snykはこの2つの問題を解決してくれ、しかも無料です😉
導入方法は？
[無料のSnykアカウントを作成](https://app.snyk.io/login)し、 GitHubまたはBitbucketフロントエンドプロジェクトを接続します。これにより、Snykは修正プルリクエストを自動的に検出して作成します。
 
#####Angularアプリの脆弱性を修正する

Angularのセキュリティ問題を見つけるためのもう一つの手っ取り早い方法は、Snyk CLIを使うことです。
```console
npm install -g snyk
snyk test
```
<img src="https://snyk.io/wp-content/uploads/image3-5.png">
Snyk CLIは、これらを報告しないnpm監査とは異なり、既知のCVEの脆弱性以上のものを提供します
出典：[Angular vs React：セキュリティベイクオフ2019 ](https://snyk.io/blog/angular-vs-react-security-bakeoff-2019/)
Snykは、修正バージョンにアップグレードするための実用的な修復アドバイスを提供します。
Angularセキュリティスキャナーに近いものを探している場合は、オープンソースの依存関係を追跡し、通知を受け取り、脆弱性が発見されたら修正する方法としてSnykをチェックしてください。
 
 
 
#####さらにお勧めの記事：
* AngularJSを使用して積極的な開発を行っている方は、[10のAngularJS Securityの基本的なベストプラクティス](https://snyk.io/blog/angularjs-security/)が役立ちます。
* AngularとReactは、セキュリティ体制にの比較。詳細な[JavaScriptフレームワークセキュリティレポート](https://snyk.io/blog/angular-vs-react-security-bakeoff-2019/)をリリースしました。
 
#####Angularは安全ですか？
新しいAngularフレームワーク（Angular 2以降）は、既知のセキュリティ脆弱性を示さない、デフォルトで安全なフレームワークとみなされています。それに比べて、前身のAngularJSには、 2020年6月の時点で[25件以上の既知のセキュリティの脆弱性](https://snyk.io/vuln/npm:angular)があります。[Angularのセキュリティのベストプラクティス](https://snyk.io/blog/angular-security-best-practices/)に従っていることを確認し、Angular、React、その他のプロジェクトのnpmモジュールエコシステムのセキュリティについて深く掘り下げた[JavaScriptフレームワークセキュリティレポート](https://snyk.io/blog/javascript-frameworks-security-report-2019/)を確認してください。 
 
#####angularアプリケーションをセキュアにするには？
 
安全なAngularアプリケーションを確保するためのいくつかの重要な基本ガイドラインは次のとおりです。
1. 開発者として、XSSから保護するための「Angular Way」とそのベストプラクティスに従っていることを確認します。たとえば、これは、innerHTMLを使用したり、ユーザー入力を連結して生成されたテンプレートを使用したり、ネイティブDOMAPIを使用してHTML要素を操作したりしないことを意味します。
2. Angularプロジェクトをスキャンして、セキュリティの脆弱性をもたらすコンポーネントがないか確認してください。あなたがAngular独自のセキュリティプラクティスに従っていたとしても、他のモジュール作者はそうではないかもしれず、深刻な問題にさらされることになります。スキャンするだけでなく、潜在的な新しい問題を修正し、監視してください。Snykはその点で優れており、[プロジェクトに簡単に接続できる無料のツール](https://snyk.io/product/open-source-security-management/)です。[Angularセキュリティのベストプラクティス](https://snyk.io/blog/angular-security-best-practices/)の詳細をご覧ください。

#####angularとreactのどちらがより安全か？
Angularプロジェクト（Angular 2+）には、公に知られているセキュリティの脆弱性はありません。[Reactには2つのセキュリティの脆弱性](https://snyk.io/vuln/npm:react)がありますが、それらは2017年と古く、あなたはすでにそれよりも新しいバージョンを使っているでしょう。Angularの前身である[AngularJSには、25件以上のキュリティの脆弱性](https://snyk.io/vuln/npm:angular)があります。まだ開発中または保守中の場合は、[Snykなどの無料のデヴェロッパファーストセキュリティツール](https://snyk.io/product/open-source-security-management/)を使用してプロジェクトをスキャンしてください。このトピックに関しては、AngularエコシステムとReactエコシステムの両方のセキュリティの状態を調査している[JavaScriptフレームワークセキュリティレポート](https://snyk.io/blog/javascript-frameworks-security-report-2019/)を読んでみてください。
 
#####angularは入力をサニタイズしますか
Angularのデフォルトでは、安全な補間のために二重中括弧({{}})を使用するなど、Angular Wayの安全なコーディング方法に従っていれば、XSSにつながる可能性がある危険なテキストはすべて出力エンコードされます。ただし、AngularのinnerHTMLバインディングを使用する場合、Angularは危険なコンテンツをサニタイズすることでユーザーを保護するために最善を尽くします。しかし、これはユーザー入力を追加する際の最後の手段であるべきです。

---

記事の後半、React推し？と感がありましたね:sweat_smile:

######最後まで、読んでいただき、ありがとうございました！

---
Contents provided by:
Jesse Casman, Fumiko Doi, Content Strategists for Snyk, Japan, and Randell Degges, Community Manager for Snyk Global