web-dev-qa-db-ja.com

Angular 2:HTMLをサニタイズするとdiv idで一部のコンテンツが削除されます-これはバグですか、それとも機能ですか?

私が使う <div [innerHTML]="body"></div>エスケープされていないHTMLをテンプレートに渡し、属性bodydividに渡すとき、Angular throw:

警告:HTMLをサニタイズすると一部のコンテンツが削除されました( http://g.co/ng/security#xss を参照)。警告:HTMLをサニタイズすると一部のコンテンツが削除されました( http://g.co/ng/security#xss を参照)。警告:HTMLをサニタイズすると一部のコンテンツが削除されました( http://g.co/ng/security#xss を参照)。

plunkerを参照

それでなぜこれを言うのですか? iddivは何が危険ですか?このバグはありますか?

22
ktretyak

これは、id属性が安全ではないためです。

これは私の答えではありませんが、あなたの質問に答えます: https://security.stackexchange.com/questions/88973/why-do-id-attributes-need-stricter-validation


idおよびnameの場合、これらの属性はDOMの参照ポイントとして頻繁に使用されます。

攻撃者がこれらの参照ポイントを偽装できる場合、既存のスクリプトをだまして設計以外の場所から値を取得および設定できる可能性があり、使用されるコンテキストによっては危険な場合があります


私からのメモ:彼の投稿の残りの部分では、name属性について説明していますが、上記の内容をまだ理解していない場合は、このすべての背後にあるアイデアを理解できます。


これは、名前と値のペアを識別するためにnameが使用されるHTMLフォームにも適用されます。たとえば、Webサイトが出力時に特定のフォームフィールドをエンコードしない場合でも、フォームフィールドはサーバーで生成され、フォームはトークンを使用してCSRFから保護されるため、通常の手段では利用できません。ただし、攻撃者は、フォームの送信時に実行するXSSペイロードを含むnameで使用されるパラメーターを使用して、ユーザーにURLを訪問させることができます。

例えば通常の使用:

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

フォームをレンダリングします

<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>

そして、出力を次のように取得します

Thank you for buying from Bob's Supplies.

ただし、攻撃者は次のようにユーザーにリンクを送信できます。

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

この時点でアプリケーションは正しくHTMLエンコードされているため、フォームは次のようにレンダリングされます。

<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>

これは、次のように出力を取得します

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

このページは信頼できるため、shop_nameパラメーターをHTMLエンコードしないため、重複がある場合、アプリケーションフレームワークは常に最初の値を取得します。非常に不自然でしたが、それがポイントを示すために私の頭に落ちた最初のものでした。

7
Ced

簡単な解決策は、次のようなパイプを書くことです

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);
  }
}

あなたのhtmlファイルを追加します。

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

NgDompurify libraryを使用することもできます。 DomPurifyによりコンテンツをより適切にサニタイズでき、angularデフォルトサニタイザーですべての問題を解決します。

0
marsibarsi