에러 백과

리소스 URL 컨텍스트에 안전하지 않은 값 사용

템플릿이나 호스트 바인딩에서 <iframe src>나 <link href>처럼 외부 리소스를 불러오는 속성에 명시적으로 신뢰하도록 표시하지 않은 값을 설정하면 Angular가 unsafe value used in a resource URL context 메시지와 함께 이 오류를 발생시킵니다.

리소스 URL은 일반 URL과 다르게 취급됩니다. Angular는 일반 URL을 정제(sanitize)할 수 있지만 임의의 리소스 URL을 안전하게 만들 수는 없습니다. 이러한 속성은 브라우저가 외부 콘텐츠를 가져와 실행하도록 하기 때문입니다. 따라서 Angular는 신뢰하지 않는 값을 정제하려 하지 않고 거부합니다.

이 검사를 수행하는 속성은 다음과 같습니다.

요소 속성
<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()를 호출해도 오류가 발생합니다. sanitize()는 리소스 URL 컨텍스트에서 임의의 문자열을 안전하게 만들 수 없으므로 이때는 NG05201이 발생합니다.

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을 절대로 전달하지 마세요. 공격자가 악성 스크립트를 포함한 임의의 콘텐츠를 불러올 수 있게 됩니다. 값을 완전히 통제할 수 있을 때만 사용하세요.

자세한 내용은 보안 가이드를 참고하세요.