angular/angular · warning

WARNING: sanitizing unsafe URL value ${url} (see ${XSS_SECUR

Error message

WARNING: sanitizing unsafe URL value ${url} (see ${XSS_SECURITY_URL})

What it means

_sanitizeUrl - used for URL-context bindings like [href], [src], and sanitize(SecurityContext.URL, …) - tested the value against SAFE_URL_PATTERN: it must not start with javascript: and must either begin with a valid scheme ([a-z0-9+.-]+:) or be a relative/scheme-relative path without masked colons (e.g. javascript:). Failing values are prefixed with 'unsafe:' (making the link inert) and dev mode logs this warning showing the offending URL.

Source

Thrown at packages/core/src/sanitization/url_sanitizer.ts:44

 *     (before port).
 *
 * The pattern disallows &, used in HTML entity declarations before
 * one of the characters in [/?#]. This disallows HTML entities used in the
 * protocol name, which should never happen, e.g. "http" for "http".
 * It also disallows HTML entities in the first path part of a relative path,
 * e.g. "foo<bar/baz".  Our existing escaping functions should not produce
 * that. More importantly, it disallows masking of a colon,
 * e.g. "javascript:...".
 *
 * This regular expression was taken from the Closure sanitization library.
 */
const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:\/?#]*(?:[\/?#]|$))/i;
export function _sanitizeUrl(url: string): string {
  url = String(url);
  if (url.match(SAFE_URL_PATTERN)) return url;

  if (typeof ngDevMode === 'undefined' || ngDevMode) {
    console.warn(`WARNING: sanitizing unsafe URL value ${url} (see ${XSS_SECURITY_URL})`);
  }

  return 'unsafe:' + url;
}

View on GitHub (pinned to 51cb07e980)

Solutions

  1. Fix the URL value: use a real scheme (https://…), a relative path, or '#' placeholders instead of javascript: URLs.
  2. Replace javascript: href links with type="button" buttons bound to (click).
  3. If the URL is guaranteed safe by construction, wrap it with DomSanitizer.bypassSecurityTrustUrl in the component and bind the SafeUrl.

Example fix

<!-- before -->
<a [href]="'javascript:void(0)'" (click)="open()">Open</a>

<!-- after -->
<button type="button" (click)="open()">Open</button>
Defensive patterns

Strategy: type-guard

Validate before calling

// Mirror Angular's SAFE_URL_PATTERN before assigning the value
const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:\/?#]*(?:[\/?#]|$))/i;
function safeUrlOrNull(url: string): string | null {
  const u = String(url);
  return u.match(SAFE_URL_PATTERN) ? u : null;
}

Type guard

function isSafeUrl(url: unknown): url is string {
  return typeof url === 'string' && /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:\/?#]*(?:[\/?#]|$))/i.test(url);
}

Prevention

When it happens

Trigger: [href]="javascript:void(0)" or a value like 'java&#115;cript:alert(1)' with a masked colon; a malformed URL containing characters such as '<' that fail the pattern; URLs assembled from user input that end up as 'undefined' or contain encoded colons.

Common situations: Legacy markup migrated to property bindings; dynamic URL construction from form input; template literals that produce garbage when a variable is missing; sanitizing deep-link parameters.

Related errors


AI-assisted analysis of angular/angular@51cb07e980 (2026-08-22). Data as JSON: /api/errors/830038d4beddf59a. Report an issue: GitHub.