錯誤百科

在資源 URL 情境中使用不安全的值

當範本或宿主繫結把載入外部資源的屬性(例如 <iframe src> 或 <link href>)設定為未被明確標示為受信任的值時,Angular 會拋出此錯誤,訊息為 unsafe value used in a resource URL context。

資源 URL 的處理方式與一般 URL 不同。Angular 可以淨化普通的 URL,但無法讓任意的資源 URL 變安全,因為這些屬性會讓瀏覽器擷取並執行外部內容。因此 Angular 會拒絕不受信任的值,而不是嘗試淨化它們。

觸發此檢查的屬性如下:

Element Attribute(s)
<base> href
<embed> src
<frame> src
<iframe> src
<link> href
<object> codebase, data

除錯方式

把任何普通字串繫結到上述屬性之一時都會拋出此錯誤,即使是看起來像靜態的 URL:

@Component({
  selector: 'app-root',
  template: `<iframe [src]="url"></iframe>`,
})
export class App {
  url = 'https://example.com/embed';
}

把值以 SecurityContext.URL 傳給 DomSanitizer.sanitize() 也沒有幫助。sanitize() 傳回的是普通字串,而普通字串在資源 URL 情境中永遠不會被接受:

@Component({
  selector: 'app-root',
  template: `<iframe [src]="sanitized"></iframe>`,
})
export class App {
  private readonly sanitizer = inject(DomSanitizer);
  sanitized = this.sanitizer.sanitize(SecurityContext.URL, 'https://example.com/embed'); // still throws NG0904
}

改以 SecurityContext.RESOURCE_URL 呼叫 sanitize() 同樣會拋出錯誤,但錯誤碼是 NG05201,因為 sanitize() 無法讓任意字串在資源 URL 情境中變安全。

如果該 URL 來自受信任且受控制的來源,請使用 DomSanitizer.bypassSecurityTrustResourceUrl 把它標示為安全:

import {DomSanitizer, SafeResourceUrl} from '@angular/platform-browser';
import {Component, inject} from '@angular/core';

@Component({
  selector: 'app-root',
  template: `<iframe [src]="safeUrl"></iframe>`,
})
export class App {
  safeUrl: SafeResourceUrl = inject(DomSanitizer).bypassSecurityTrustResourceUrl(
    'https://example.com/embed',
  );
}

CRITICAL: bypassSecurityTrustResourceUrl 是逃生口,不是淨化器。絕不要把使用者提供的 URL 傳給它,那會讓攻擊者載入任意內容,包括惡意指令碼。只有在該值完全由你控制時才使用它。

更多資訊請見安全性指南。