Angular 2: sanitizing HTML stripped some content w

2020-02-20 07:11发布

问题:

I use <div [innerHTML]="body"></div> to pass unescaped HTML to my template, and when I pass to body div with attribute id, Angular throw:

WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss). WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss). WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).

See. plunker

So why it says this? What can be dangerous id in div? Could this bug?

回答1:

It is because id attribute is not safe.

This is not my answer but it will answer your question : https://security.stackexchange.com/questions/88973/why-do-id-attributes-need-stricter-validation


For id and name, these attributes are frequently used as reference points in the DOM.

If an attacker can spoof these reference points, she may be able trick existing scripts into getting and setting values from places other than designed, which may be dangerous depending on the context that is is used.


Note from me: The rest of his post talks about the name attribute, but you'll get the idea behind all this if you don't already by what's above


This also applies to HTML forms where name is used to identify the name/value pair. For example, if a website does not encode a particular form field when it is output, but since the form field is server generated and the form is protected against CSRF by the use of tokens it cannot be exploited by normal means. However, an attacker may be able to entice a user to visit a URL with a parameter that is used in name, containing an XSS payload to execute on submission of the form.

e.g. Normal use:

https://example.com/product?item_name=watch&qty=1

which renders a form

<form>

<input type="hidden" name="watch" value="1" />
<input type="hidden" name="shop_name" value="Bob's Supplies" />
<input type="hidden" name="anti-csrf" value="asdjasodhoai" />

<input type="submit" value="Click here to buy" />

</form>

And then gets output as

Thank you for buying from Bob's Supplies.

However, an attacker could send a link to the user like so:

https://example.com/product?item_name=shop_name&qty=<script>alert('xss')</script>

As the application is correctly HTML encoding at this point it renders the form as

<form>

<input type="hidden" name="shop_name" value="&lt;script&gt;alert(&#039;xss&#039;)&lt;/script&gt;" />
<input type="hidden" name="shop_name" value="Bob's Supplies" />
<input type="hidden" name="anti-csrf" value="asdjasodhoai" />

<input type="submit" value="Click here to buy" />

</form>

This then gets output as

Thank you for buying from <script>alert('xss')</script>.

since this page doesn't HTML encode the shop_name parameter because it is trusted and the application framework always takes the first value in case of duplicates. Very contrived, but it was the first thing that fell into my head to demonstrate the point.



回答2:

Simple solution is to write pipe like

import { Pipe, PipeTransform } from "@angular/core";
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

@Pipe({
  name: 'sanitizeHtml'
})
export class SanitizeHtmlPipe implements PipeTransform {

  constructor(private _sanitizer:DomSanitizer) {
  }

  transform(v:string):SafeHtml {
    return this._sanitizer.bypassSecurityTrustHtml(v);
  }
}

add in your html file add pile like

  <td *ngIf="i>0" [innerHTML]="entry.attributes[i] | sanitizeHtml"></td>


回答3:

You can also use NgDompurify library. It can sanitize your content better due DomPurify and solves all your problems with angular default sanitizer.