과도하게 허용적인 URL 허용 목록 (AngularJS $sce)

Overly Permissive URL Whitelist (AngularJS $sce)

설명

AngularJS의 $sceDelegateProvider.resourceUrlWhitelist()는 템플릿, ng-include, 리소스 로드 등 실행 맥락에서 사용할 수 있는 URL을 허용 목록으로 제한합니다. AngularJS 1.8.1 이후에는 같은 설정을 trustedResourceUrlList() 이름으로 사용하는 것이 권장됩니다. 그러나 스킴 와일드카드(*://), 호스트 이중 와일드카드(**), 최상위 도메인 와일드카드(example.* 등)를 사용하면 공격자가 소유한 도메인이나 유사 도메인을 통과시켜 악성 템플릿/리소스를 로드하게 만들 수 있습니다. 그 결과 XSS로 이어져 임의의 JavaScript 실행, 세션 탈취, 데이터 유출이 가능해집니다.

AngularJS의 공식 지원은 2022년 1월에 종료되었습니다. 이 예시는 AngularJS 1.8.x의 기존 코드를 유지보수할 때 참고하세요.

잠재적 영향

  • XSS(크로스 사이트 스크립팅): 느슨한 허용 규칙으로 공격자 도메인에서 템플릿/리소스를 로드해 악성 JavaScript가 실행될 수 있음
  • 민감 정보 유출: 세션 토큰, 쿠키, 사용자 데이터가 외부로 전송될 수 있음
  • 콘텐츠 변조 및 피싱: 신뢰된 화면에 악성 템플릿을 삽입하여 UI를 속이거나 피싱을 유도할 수 있음
  • 공급망 공격 확대: 최상위 도메인 와일드카드/이중 와일드카드로 유사 도메인(CDN 위장)을 허용하여 악성 리소스를 배포할 수 있음

해결 방법

  • 허용 목록을 최소 권한으로 설계: 가능한 'self'만 허용하거나, 신뢰되는 소수의 정확한 origin만 지정하세요.
  • 스킴 명시: *:// 대신 https://를 명시하세요. http://는 원칙적으로 금지하고 필요 시 별도 검토 후 제한적으로 허용하세요.
  • 허용 목록의 호스트 제한: **는 사용하지 말고 필요한 경우에만 *.sub.example.com처럼 한 단계 서브도메인으로 한정하세요.
  • 최상위 도메인(TLD) 와일드카드 금지: example.* / example.** 대신 정확한 도메인(예: example.co.kr, example.com)을 나열하세요.
  • 차단 목록 병행: AngularJS 1.8.x에서는 bannedResourceUrlList()로 data:, blob:, http: 등 위험 스킴/도메인을 명시적으로 차단하세요. 기존 코드의 resourceUrlBlacklist()는 레거시 이름입니다.
  • 검증/테스트: 변경 시 정규식/패턴이 과도하게 매칭되지 않는지 테스트 케이스로 검증하고, 보안 리뷰를 필수화하세요.
  • 추가 방어: CSP(Content Security Policy)로 외부 리소스 출처를 한 번 더 제한하세요.

예시

변경 전

javascript
angular.module("shopApp", []).config(function ($sceDelegateProvider) {
  // 과도하게 허용적인 패턴들
  $sceDelegateProvider.resourceUrlWhitelist([
    "*://*.trusted.net/*", // BAD: 스킴 와일드카드
    "https://**.mycdn.com/*", // BAD: 호스트 이중 와일드카드
    "https://partner.*/*", // BAD: TLD 와일드카드
  ]);
});

변경 후

javascript
angular.module("shopApp", []).config(function ($sceDelegateProvider) {
  // 최소 권한의 정확한 출처만 허용
  $sceDelegateProvider.resourceUrlWhitelist([
    "self",
    "https://static.mycorp.com/*",
    "https://cdn.mycorp.co.kr/*",
    "https://assets.sub.mycorp.com/*", // 필요한 경우에만 특정 서브도메인 명시
  ]);

  // 명시적으로 위험 스킴/도메인을 차단 (선택)
  $sceDelegateProvider.bannedResourceUrlList(["http://**", "data:**", "blob:**"]);
});

설명:

  • 변경 전: 스킴 와일드카드(*://), 이중 와일드카드(**), TLD 와일드카드(example.*)는 공격자가 제어하는 도메인이나 유사 도메인까지 허용합니다. AngularJS가 해당 URL에서 템플릿/리소스를 불러오면 악성 코드가 실행되어 XSS, 데이터 탈취로 이어질 수 있습니다.
  • 변경 후: 'self'와 소수의 신뢰된 HTTPS origin만 정확히 지정하여 불필요한 출처를 차단합니다. 스킴은 https://로 명시하고, 허용 목록에 이중/TLD 와일드카드를 사용하지 않습니다. 추가로 bannedResourceUrlList()로 위험 스킴을 차단해 공격 표면을 더 줄입니다.

참조