I'm trying to construct an url to pass it inside the src attributes of an iframe. But I always get the exception unsafe value used in a resource URL context
and I'm struggling to understand how to correctly sanitize the url.
I could make it work with domSanitizer.bypassSecurityTrustResourceUrl(myCustomUrlAsString)
but from what I understand, by doing so, I'm just disabling the security. Even tho it could be acceptable as the url is not constructed with any user input, I want to understand how the sanitization work.
My ng component code:
export class MyAngularComponent implements OnInit {
public url: SafeResourceUrl | null;
constructor(private domSanitizer: DomSanitizer) {}
ngOnInit() {
const url = new URL('https://example.org?param1=foo');
this.url = this.domSanitizer.sanitize(SecurityContext.URL, url.toString());
}
}
My template: <iframe [src]="url" width="100%" height="100%"></iframe>
When checking the sanitized value, it's just a string or that same url. But the template rendering triggers the exception. Shouldn't the sanitize function return a Safe Url to avoid this exception? Or should I had the bypassSecurityTrustResourceUrl
in any case after the sanitize
?
Tx for the help
CodePudding user response:
I could make it work with domSanitizer.bypassSecurityTrustResourceUrl(myCustomUrlAsString) but from what I understand, by doing so, I'm just disabling the security. Even tho it could be acceptable as the url is not constructed with any user input, I want to understand how the sanitization work.
That's exactly what you need to do. You're marking the URL as trusted which I assume it is because it's not user input. You could wrap the sanitizer like so:
domSanitizer.bypassSecurityTrustResourceUrl(this.domSanitizer.sanitize(SecurityContext.URL, url.toString()))
to make sure nothing crazy is in there but it's not bad practice in this case to mark it as trusted.
Shouldn't the sanitize function return a Safe Url to avoid this exception?
As for this, I expected the same as you but figured that it probably doesn't or can't check wether the URL is safe or not so it just always throws that exception unless you bypass it.
CodePudding user response:
Let say we are passing invalid URL to bypassSecurityTrustResourceUrl directly, It will assume we are passing valid url and return SafeResourceUrl object without throwing any error.
Example
const invalidURL = `javascript:alert('Moar XSS!')`;
const url = this.domSanitizer.sanitize(SecurityContext.URL,invalidURL);
//It will skip validing URL and will not throw any error.
sanitize method will add additional check to make the url safe to use.
const invalidURL = `javascript:alert('Moar XSS!')`;
const url = this.domSanitizer.sanitize(SecurityContext.URL, url.toString());
//This additional check will ensure the above string is invalid string.
this.domSanitizer.bypassSecurityTrustResourceUrl(url);
It is better practice to use the sanitize URL before passing it to the bypassSecurityTrustResourceUrl method to make the url safe.
const url = this.domSanitizer.sanitize(SecurityContext.URL, url.toString());
this.url = this.domSanitizer.bypassSecurityTrustResourceUrl(url);