keepcalculator

06 Numbers and Powers

Angular ng0910 fix unsafe iframe bindings the right way

Card No. 06·40588 · Updated · Standard formula, shown below

Angular’s ng0910 error flags unsafe iframe bindings when you set the src attribute directly from a string that Angular can’t verify as safe. The right fix is to sanitize the URL with DomSanitizer.bypassSecurityTrustResourceUrl() or, better, avoid dynamic iframe URLs altogether by using a static list of allowed sources. This article explains exactly why the error happens, how to implement the fix correctly, and what pitfalls to avoid.

What is ng0910 and why does it happen?

Angular 9 introduced stricter security checks for iframe bindings to prevent cross-site scripting (XSS) attacks. When you write <iframe [src]="someString"></iframe>, Angular’s template compiler sees that the bound value is not a trusted SafeResourceUrl. It then throws the ng0910 error at runtime to stop you from accidentally injecting a malicious URL.

The error message typically reads: “Can’t bind to ‘src’ since it isn’t a known property of ‘iframe’.” Wait, that’s a different error. The actual ng0910 message is: “NG0910: Unsafe iframe bindings are disallowed. Use DomSanitizer to make the URL safe.” It appears in the console when you try to bind a plain string to src on an iframe element.

Angular’s security model treats iframes as high-risk because they can load arbitrary content. The framework requires you to explicitly mark a URL as safe for resource loading, otherwise it refuses to render it.

The two legitimate ways to fix it

There are two main approaches, and choosing the right one depends on your use case.

1. Use DomSanitizer (when you really need dynamic URLs)

Inject DomSanitizer into your component and call bypassSecurityTrustResourceUrl() on the URL string. This tells Angular, “I’ve verified this URL, trust it.” Here’s a typical example:

import { DomSanitizer, SafeResourceUrl } from '@angular/core';

@Component({...})
export class VideoComponent {
  safeUrl: SafeResourceUrl;
  constructor(private sanitizer: DomSanitizer) {
    this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl('https://example.com/embed/video');
  }
}

Then in the template: <iframe [src]="safeUrl"></iframe>. This works, but it’s a blunt tool. You’re bypassing Angular’s sanitization entirely, so you must be 100% sure the URL comes from a trusted source (e.g., a constant, not user input).

2. Use a static list (the safer alternative)

If the iframe URLs come from a known set (like YouTube, Vimeo, or your own domain), define them as constants and map user input to those constants. For example:

const ALLOWED_VIDEOS = {
  intro: 'https://www.youtube.com/embed/abc123',
  tutorial: 'https://player.vimeo.com/video/456789'
};

@Component({...})
export class VideoComponent {
  videoUrl = ALLOWED_VIDEOS['intro'];
}

Now the template binds to videoUrl, which is always a safe constant. No sanitizer needed, no error. This is the recommended approach because it eliminates the risk of XSS entirely.

Why you should avoid bypassSecurityTrustResourceUrl

The method’s name says it all: you’re bypassing security. If you use it with any URL that could be influenced by a user, you open the door to javascript: URLs or data URIs that execute code in your app’s context. For example, an attacker could craft javascript:alert(document.cookie) and if you pass that to bypassSecurityTrustResourceUrl, Angular will happily put it in the iframe’s src, leading to XSS.

Even with a seemingly safe domain, you should validate the URL against a whitelist before calling the bypass method. A common pattern is:

sanitizeUrl(url: string): SafeResourceUrl {
  const allowed = ['youtube.com', 'vimeo.com'];
  if (allowed.some(domain => url.includes(domain))) {
    return this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
  throw new Error('URL not allowed');
}

This adds a layer of protection, but the static list approach is still simpler and safer.

How to fix ng0910 in an existing project

If you’re seeing this error right now, follow these steps:

  1. Find the iframe binding in your template that uses a property like [src]="someVar".
  2. Check where someVar is assigned. If it’s a hardcoded string, move it to a constant and bind to that constant directly. That alone fixes the error without sanitizer.
  3. If someVar is computed from user input or an API response, you must sanitize. Inject DomSanitizer into the component and create a method that returns a SafeResourceUrl after validating the domain.
  4. In the template, call the method: <iframe [src]="getSafeUrl(someVar)"></iframe> or assign the sanitized value to a property in ngOnInit.
  5. Test with a few different URLs to ensure the error is gone.

Remember, the error only appears in development mode. In production, Angular might not throw the error but will still block the binding, so the iframe simply won’t load. Fixing it properly is essential for both environments.

Common mistakes when fixing ng0910

  • Using bypassSecurityTrustUrl instead of bypassSecurityTrustResourceUrl – The former is for URLs used in href, not iframe src. The latter is specifically for resource URLs.
  • Sanitizing in the template – Calling a method that returns a SafeResourceUrl directly in the template works, but it runs on every change detection cycle, which is inefficient. Assign it once to a property.
  • Forgetting to import SafeResourceUrl type – If you declare a property as SafeResourceUrl, you need to import it from @angular/core to avoid TypeScript errors.
  • Binding to src on a regular element – The error only occurs on iframe. If you’re seeing it on a div, you’re probably using a custom element that Angular doesn’t recognize.

What about src with [attr.src]?

Some developers try to work around the error by using [attr.src]="someVar" instead of [src]. This is a bad idea. The attr. binding bypasses Angular’s property binding, so the URL is set as an attribute without any sanitization. This will still trigger ng0910 in development (since Angular checks attribute bindings too) and is even more dangerous because it bypasses all security checks. Always use property binding with a sanitized value.

Frequently Asked Questions

Does ng0910 appear in production builds?

No, the error is only thrown in development mode. In production, Angular silently refuses to set the iframe’s src, so the iframe appears empty. This makes it even more important to fix it during development.

Can I disable this check globally?

There is no official way to disable ng0910. You could suppress it by using bypassSecurityTrustResourceUrl everywhere, but that defeats the purpose of Angular’s security model. The better approach is to fix the bindings properly.

Why does Angular treat iframes differently from images?

Iframes can load arbitrary HTML and JavaScript, making them a much larger attack surface than images. Angular’s security model is stricter for resource URLs (like iframe src) than for regular URLs (like image src) because the potential damage is greater.

Is it safe to use bypassSecurityTrustResourceUrl for YouTube embeds?

If the URL is hardcoded to YouTube’s embed domain, yes. But if the video ID comes from user input, you should validate that the full URL matches a pattern like https://www.youtube.com/embed/ followed by a valid video ID. Never pass a raw user-provided string to the bypass method.

What if I need to load a blob URL in an iframe?

Blob URLs are created by your own code, so they are generally safe. You can create a SafeResourceUrl from a blob URL using the same sanitizer method. However, you should still ensure the blob content is not user-controlled in a harmful way.

Does this error affect Angular versions before 9?

No, ng0910 was introduced in Angular 9. In earlier versions, unsafe iframe bindings were not checked, which was a security risk. If you’re on an older version, you should upgrade to get this protection.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →