Skip to content

fix(core): block dangerous data: and vbscript: URLs in URL sanitizer#67692

Open
bangel251022 wants to merge 1 commit intoangular:mainfrom
bangel251022:fix/url-sanitizer-dangerous-schemes
Open

fix(core): block dangerous data: and vbscript: URLs in URL sanitizer#67692
bangel251022 wants to merge 1 commit intoangular:mainfrom
bangel251022:fix/url-sanitizer-dangerous-schemes

Conversation

@bangel251022
Copy link

Summary

The URL sanitizer (_sanitizeUrl) currently only blocks javascript: URLs. This leaves other potentially dangerous URL schemes unblocked:

  • data:text/html — can execute scripts in older browsers and certain WebView environments
  • vbscript: — script execution in legacy Internet Explorer
  • data: with no subtype (e.g. data:,<script>...) — defaults to text/plain but has been used in XSS attacks
  • data:application/xhtml+xml, data:text/xml — can contain executable script content

Changes

This PR extends the URL sanitizer regex to block vbscript: and dangerous data: subtypes while continuing to allow safe media data URIs:

  • data:image/* — allowed (inline images)
  • data:video/* — allowed (inline video)
  • data:audio/* — allowed (inline audio)
  • data:text/html — blocked
  • data:application/* — blocked
  • data:text/* — blocked
  • data:, (bare) — blocked
  • vbscript:* — blocked

This also resolves a longstanding TODO in html_sanitizer.ts that has been open since the sanitizer was originally written:

// TODO(martinprobst): Special case image URIs for data:image/...

Security Note

data:image/svg+xml is allowed because SVG loaded via <img src> is sandboxed by browsers (scripts do not execute). For <a href> contexts, modern browsers (Chrome 60+, Firefox 59+) block top-level navigation to data: URLs entirely.

Migration

Applications that rely on non-media data: URLs (e.g. data:text/plain, data:application/pdf) in sanitized URL contexts should use DomSanitizer.bypassSecurityTrustUrl() to explicitly mark them as trusted.

Test Plan

  • Added tests for vbscript: URL variants (3 cases, case-insensitive)
  • Added tests for dangerous data: URLs (9 cases including base64, bare data:, various MIME types)
  • Added additional safe data:image/* test cases (svg+xml, gif)
  • Verified all existing valid URL tests still pass
  • Fixed test description typo (validinvalid for invalid URL test cases)

The URL sanitizer previously only blocked `javascript:` URLs via a
negative lookahead. This left other potentially dangerous URL schemes
unblocked, including `data:text/html` (which can execute scripts in
some environments), `vbscript:` (script execution in legacy IE), and
bare `data:` URIs with no explicit media type.

This change extends the URL sanitizer to also block:
- `vbscript:` URLs
- `data:` URLs except for safe media subtypes (image/*, video/*, audio/*)

Safe media data: URIs (e.g. `data:image/png;base64,...`) continue to be
allowed as they are commonly used for inline images and do not execute
scripts when loaded via `<img src>`.

This resolves a longstanding TODO in html_sanitizer.ts to special-case
`data:image/` URIs, which has been open since the sanitizer was first
written.

Applications that rely on non-media `data:` URLs (e.g. `data:text/plain`
or `data:application/pdf`) in sanitized contexts should use
`bypassSecurityTrustUrl()` to explicitly mark them as trusted.
@google-cla

This comment was marked as outdated.

@angular-robot angular-robot bot added the area: core Issues related to the framework runtime label Mar 15, 2026
@ngbot ngbot bot added this to the Backlog milestone Mar 15, 2026
@bangel251022 bangel251022 force-pushed the fix/url-sanitizer-dangerous-schemes branch from 99a8e6f to 7254606 Compare March 15, 2026 12:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: core Issues related to the framework runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants