web-dev-qa-db-ja.com

DOMベースのXSSとHTML要素の追加

経験則として、JavaScript/JQuery(.html().append()など)を使用してHTMLを追加または削除すると、DOMベースのXSS攻撃の可能性が広がることを学びました。これは100%真実ではないというのが私の理解です。おそらく、JavaScriptでHTMLを追加/削除するための正しい安全な方法があるでしょう。私はこの「正しい方法」が何であるかについていくつかを学びたいと思っています。

例として、ユーザーが項目をリストに追加できるようにする入力フィールドがあるとします。この場合、入力は配列に追加され、将来のリクエストで送信されます。さらに、このリストには、そのリストから上記のアイテムを削除するためのボタンがあります。安全でない環境では、次のようなことをするかもしれません(否定配列):

var list = $("#my_list");

$("#add_btn").on("click", function(){
    let input = $("#input_field").val();
    list.append(
        '<li>'+input+' <button>Remove</button></li>'
    );
});


$("#my_list").on("click", "button", function(){
    $(this).closest("li").remove();
});

どのようにしてXSSの脅威なしに同じことを行うことができますか?

JSFiddle へのリンクは、さまざまな推奨ソリューションを示しています

6
FamousAv8er

文字列としてDOMを作成し、appendまたはhtmlを使用すると、実際にDOMベースのXSSになります。代わりに行うべきことは、適切な関数を使用してDOM要素を構築し、ユーザー提供の入力のみをテキストとして挿入することです。例:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<ul id=my_list class=my_list></ul>
<input type=text id=input_field value="<img src=x onerror=alert(1)>">
<button id=add_btn></button>

<script>
var list = $("#my_list");
$("#add_btn").on("click", function(){
    let input = $("#input_field").val();

    // this is insecure:
    //list.append('<li>'+input+' <button>Remove</button></li>');

    // this is secure:
    var listentry = document.createElement('li');
    listentry.innerText = input;
    list.append(listentry);
});
</script>
5
tim