35

For some reason, some of my images are being prepended with 'unsafe:', which is causing them not to be rendered.

Q) Why is this happening and how can I fix it - Is this Angular 2 being odd with whitelisting or Ionic 2?

e.g.

<p><img src="unsafe:data:image/jpeg;base64,/9.....
<p><img src="data:image/jpeg;base64,/9.....

There is nothing wrong with the image (see here), see plunkr here

The second image is rendered from Ionic 2, the first I manually removed the prefix to show it's fine.

Dave
  • 5,283
  • 7
  • 44
  • 66
  • 1
    That's the same without Angular2 or ionic when added directly to `index.html` without bootstrapping Angular and Ionic http://plnkr.co/edit/oZilVHewCeFAaIF6skMT?p=preview – Günter Zöchbauer Jun 28 '16 at 15:56
  • Hi, yeah I know, I explained what is happening in my question. The plunkr is merely there for context. – Dave Jun 28 '16 at 15:59
  • I don't think you're understanding me clearly. Sure, if you just remove them both, the page is the same, but what I'm saying is that when USING Angular 2 + Ionic 2, it is outputting the imageBase64 with that prepended. So they ARE involved. – Dave Jun 28 '16 at 16:12
  • 2
    Sorry, I guess I understand it now. I guess it is a bug if it sanitizes static template content. I think it should only sanitize bound values (I'm not a security expert though). – Günter Zöchbauer Jun 28 '16 at 16:15
  • You might be able to work around by using `bypassSecurityTrustUrl()` from https://angular.io/docs/ts/latest/api/platform-browser/index/DomSanitizationService-class.html and bind the result to `src` – Günter Zöchbauer Jun 28 '16 at 16:16
  • 1
    https://github.com/angular/angular/blob/master/modules/%40angular/platform-browser/src/security/url_sanitizer.ts#L55 – yurzui Jun 28 '16 at 16:19

6 Answers6

55

For anyone experiencing this issue, I have 'solved' it by using the following:

Class:

import {DomSanitizationService} from '@angular/platform-browser';

constructor(private _DomSanitizationService: DomSanitizationService) {}

Template:

<img [src]="_DomSanitizationService.bypassSecurityTrustUrl(imgSrcProperty)"/>

Where imgSrcProperty is the offending image base64 encoded.

I still think this is a bug!

Dave
  • 5,283
  • 7
  • 44
  • 66
  • 28
    Has since been renamed to `DomSanitizer`, I just bumped into the issue in Angular 2.1.0. – Thorsten Westheider Oct 24 '16 at 16:49
  • It is important to note that this bypasses the whole Content Security Policy (CSP), which can/or is set via the `` tag. – Dalie Nov 16 '16 at 10:55
  • @Dave Good idea, but taking couple of seconds in ionic-2. Can you please suggest another solution for the same..!!!! – Rahul_Dabhi Jan 04 '17 at 06:35
  • @Dave, Not Working for me. Followed above steps, Its adding `&` in place of `&` in my `base64 image` string. Due to this getting `net::ERR_INVALID_URL` – Vishwajit R. Shinde Oct 12 '17 at 15:37
  • Dunno - dirty hack alert: pass the result into a function and do a replace-all on & with & ? like str = str.replace(/&/g, '&') perhaps? – Dave Oct 12 '17 at 19:42
  • If you want to compile to AOT, the service should be public not private. – Chris Haines Mar 21 '19 at 13:01
  • It is important to remember that if you choose to use the template as described by @Dave in his answer ``, you need to make sure that your constructor is made public and not private, like so `constructor(public _DomSanitizationService: DomSanitizationService) {}`. Cheers – AllJs Jun 06 '21 at 09:13
20

in angular 5.2.6

class:

import { DomSanitizer } from '@angular/platform-browser';
constructor(public _DomSanitizationService: DomSanitizer ) {}

Template

<img [src]="_DomSanitizationService.bypassSecurityTrustUrl(imgSrcProperty)"/>
Milad Jafari
  • 970
  • 10
  • 15
8

I would like to add an additional answer, so some of you will not have to debug for ages.

We also came across this problem together with Ionic+Angular on iOS (WKWebView) and found out, that Base64 data urls are also considered "unsafe" once the Base64 string contains line breaks. Either MS Windows style CRLF or LF.

We proceeded to remove those offending characters from base64 strings (an external interface was "pretty printing" them), which ultimately resolved the issue for us.

Before applying the bypass mentioned by @Dave, I would check the string.

Wilk
  • 81
  • 1
  • 6
  • 4
    This solved my problem. I added this to my JS code to remove the line breaks and the error went away: ```mytext = mytext.replace(/(\r\n\t|\n|\r\t)/gm,"");``` – DeegC Jun 24 '18 at 17:09
  • Same error with forgotten `.` in mime type `image/.png`. Got here "data:image/${path.extension(imageFile.path)}...." – Zdeněk Mlčoch Apr 27 '19 at 23:12
0

In my case, I discovered, after have banged my head against the wall several times, that a litle and innocent whitespace in the end of the image url can make Ionic/Angular issue this error.

Nowdeen
  • 1,401
  • 14
  • 20
0

It worked for me, although in Angular 11 its slightly different. The DomSanitationService is now The DomSanitizer:

import {DomSanitizer } from '@angular/platform-browser';

And if you want to use this in your component html, you need to set it public:

constructor(public domSrv: DomSanitizer)

Then its easy to use:

<img *ngIf="picture" [src]="domSrv.bypassSecurityTrustUrl(picture)" />
Mark
  • 379
  • 3
  • 7
0

Alternative solution is to user ion-img:

<ion-img src="{{base64SVGString}}"></ion-img>
Anas
  • 711
  • 7
  • 24