Overly permissive AngularJS URL allow-lists

Overly permissive resource URL allow-lists in AngularJS $sce

Description

AngularJS's $sceDelegateProvider.resourceUrlWhitelist() limits the URLs that may supply templates, ng-include content, and other executable resources. Since AngularJS 1.8.1, trustedResourceUrlList() is the preferred name for the same setting. Scheme wildcards (*://), double host wildcards (**), or top-level-domain wildcards such as example.* may allow attacker-owned or lookalike domains to supply malicious resources. This can lead to XSS, arbitrary JavaScript execution, session theft, or data exposure.

Official AngularJS support ended in January 2022. These examples are for maintaining existing AngularJS 1.8.x code.

Potential impact

  • Broad rules may load malicious templates or resources from an attacker's domain and enable XSS.
  • Session tokens, cookies, or user data may be sent to an attacker.
  • Injected templates may alter a trusted interface or display phishing content.
  • Top-level-domain or double wildcards may admit lookalike CDN domains that distribute malicious resources.

Remediation

  • Keep the allow-list minimal. Use only 'self' where possible, or specify a few exact trusted origins.
  • Specify https:// instead of *://. Reject http:// unless a separately reviewed need justifies a limited exception.
  • Avoid ** in allow-list host patterns. If needed, restrict a wildcard to one subdomain level, such as *.sub.example.com.
  • List exact domains such as example.co.kr or example.com instead of TLD wildcards such as example.* or example.**.
  • In AngularJS 1.8.x, use bannedResourceUrlList() to explicitly deny risky schemes or domains, including data:, blob:, and http:. resourceUrlBlacklist() is the legacy name.
  • Test changed regular expressions or patterns for unintended matches and include them in security review.
  • Use CSP (Content Security Policy) to further restrict external resource origins.

Examples

Before

javascript
angular.module("shopApp", []).config(function ($sceDelegateProvider) {
  // Overly permissive patterns
  $sceDelegateProvider.resourceUrlWhitelist([
    "*://*.trusted.net/*", // BAD: scheme wildcard
    "https://**.mycdn.com/*", // BAD: double wildcard in the host
    "https://partner.*/*", // BAD: TLD wildcard
  ]);
});

After

javascript
angular.module("shopApp", []).config(function ($sceDelegateProvider) {
  // Allow only the exact origins required
  $sceDelegateProvider.resourceUrlWhitelist([
    "self",
    "https://static.mycorp.com/*",
    "https://cdn.mycorp.co.kr/*",
    "https://assets.sub.mycorp.com/*", // Specify a subdomain only when needed
  ]);

  // Explicitly block risky schemes or domains (optional)
  $sceDelegateProvider.bannedResourceUrlList(["http://**", "data:**", "blob:**"]);
});

Explanation:

  • Before: Scheme (*://), double (**), and TLD (example.*) wildcards may admit attacker-controlled or lookalike domains. Loading templates or resources from those URLs can lead to XSS and data theft.
  • After: The allow-list specifies 'self' and a few exact trusted HTTPS origins. It avoids double and TLD wildcards in the allowed hosts. A separate bannedResourceUrlList() denies risky schemes to further reduce exposure.

References