What is difference between bypassSecurityTrustResourceUrl and bypassSecurityTrustUrl

Viewed 13160

I went through angular documentation for both functions

bypassSecurityTrustUrl which says

Bypass security and trust the given value to be a safe style URL, i.e. a value that can be used in hyperlinks or <img src>

bypassSecurityTrustResourceUrl which says

Bypass security and trust the given value to be a safe resource URL, i.e. a location that may be used to load executable code from, like <script src>, or <iframe src>.

both of the above is used to bypass security and trust.

I was bypassing the blob url for <img src> ,so before going through the documentation, my IDE (vscode) presented the above two functions, and I used bypassSecurityTrustResourceUrl and my code was like...this.

component.ts

    this.fileService.getFileBlobUrl(imgsrc).subscribe(url => {
      this.domSanitizer.bypassSecurityTrustResourceUrl
      user.bloburl = this.domSanitizer.bypassSecurityTrustResourceUrl(url);
    });

component.html

    <img [src]="user.bloburl" class="avatar" alt="avatar">

as per documentation bypassSecurityTrustUrl should be working. but I used 'bypassSecurityTrustResourceUrl`

and it is actually working!!!!

So my question is what is the difference between those two functions. why two different function if any of them can be used?

2 Answers

I'm actually creating pipes for SafeValues and also get interested in that. So I started digging and here's what I found:

DomSanitizationService:sanitization():

      case SecurityContext.URL:
        const type = getSanitizationBypassType(value);
        if (allowSanitizationBypassOrThrow(value, BypassType.Url)) {
          return unwrapSafeValue(value);
        }
        return _sanitizeUrl(String(value));
      case SecurityContext.RESOURCE_URL:
        if (allowSanitizationBypassOrThrow(value, BypassType.ResourceUrl)) {
          return unwrapSafeValue(value);
        }

So here unwrapSafeValue function is called in both types, but below we have:

DomSanitizationService:

  bypassSecurityTrustUrl(value: string): SafeUrl { 
    return bypassSanitizationTrustUrl(value); 
  }
  bypassSecurityTrustResourceUrl(value: string): SafeResourceUrl {
    return bypassSanitizationTrustResourceUrl(value);
  }

So here are 2 different functions invoked, let's go deeper.

In sanitization/bypass.ts we can find:

export function bypassSanitizationTrustUrl(trustedUrl: string): SafeUrl {
  return new SafeUrlImpl(trustedUrl);
}
export function bypassSanitizationTrustResourceUrl(trustedResourceUrl: string): SafeResourceUrl {
  return new SafeResourceUrlImpl(trustedResourceUrl);
}

and a few lines up we can find out that the only difference between them is in the returned class:

class SafeUrlImpl extends SafeValueImpl implements SafeUrl {
  getTypeName() { return BypassType.Url; }
}
class SafeResourceUrlImpl extends SafeValueImpl implements SafeResourceUrl {
  getTypeName() { return BypassType.ResourceUrl; }
}

and because of

if (actualType != null && actualType !== type) {
    // Allow ResourceURLs in URL contexts, they are strictly more trusted.
    if (actualType === BypassType.ResourceUrl && type === BypassType.Url) return true;
    throw new Error(
        `Required a safe ${type}, got a ${actualType} (see http://g.co/ng/security#xss)`);
  }

now we know that ResourceUrl is allowed everywhere where Url would be.

I found that I need to use bypassSecurityTrustResourceUrl when I sanitize images or videos and bypassSecurityTrustUrl when I sanitize files with app content like pdf or word or excel.

Related