7

So as a rule of thumb I once learned that adding or removing HTML with JavaScript/JQuery (.html(),.append(), etc) leaves yourself wide open for DOM Based XSS Attacks. It is now my understanding that this is not 100% true. Supposedly there is a correct and safe way to add/remove HTML with JavaScript. I am hoping to learn some on what this "correct way" may be.

So as an example lets say I have an input filed that allows a user to append an item to a list. In this case the input would also be added to an array to be sent in future requests. Additionally this list would have a button to remove said item from that list. In an insecure environment we might do something like the following (negating array):

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

How might one do the same but without the threat of XSS?

Link to JSFiddle demonstrating different suggested solutions

6
  • 1
    Hey, just to let you know, it's not recommended to cross post on multiple Stack Exchange sites. See this FAQ for moreCommentedMay 18, 2020 at 17:10
  • @FireQuacker I will remember this going forward, thank you.CommentedMay 18, 2020 at 17:13
  • has nothing to do with javascript per say, but I would research something like anti-forgery tokens, which makes some cross site attacks more difficult to perform... docs.microsoft.com/en-us/aspnet/web-api/overview/security/…CommentedMay 18, 2020 at 22:08
  • @pcalkins I believe you may be confusing XSS for CSRFCommentedMay 19, 2020 at 16:39
  • yes, not all that familiar with terminology... but I believe there are XSS attacks that perform CSRF attacks.... (if a user visits a phishing site or has some malware plugin installed... that kind of thing... )CommentedMay 19, 2020 at 17:23

1 Answer 1

5

Creating the DOM as string and using append or html indeed leads to DOM-based XSS. What you should do instead is to built the DOM elements using the proper functions and only inserting user-supplied input as text. Example:

<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> 
12
  • Would manipulating the DOM by removing elements open any attack vectors that could be mitigated in a similar manner? Something like $(this).closest("li").remove();CommentedMay 19, 2020 at 14:45
  • 1
    @FamousAv8er Not as far as I know (and it really shouldn't happen, as you are not building DOM elements with user input, but just calling functions on some DOM element which we don't know anything about; if that would for some reason trigger an XSS payload, I'd consider it a vulnerability in jQuery).
    – tim
    CommentedMay 19, 2020 at 15:41
  • 1
    @dandavis It doesn't. text transforms the input to a string (which it already is). But when you then insert it along with the other string (<li><button>Remove</button></li>) into the DOM via append, it will be converted to DOM elements, thus triggering any JavaScript it may contain.
    – tim
    CommentedMay 19, 2020 at 18:31
  • 1
    @tim I have updated the JSFiddle to reflect this addition jsfiddle.net/zjr907h8CommentedMay 20, 2020 at 16:39
  • 1
    @FamousAv8er The button doesn't seem to contain variables, so it should be fine as-is. But you should still be able to create it via document.createElement. To add attributes, you can use listentry.setAttribute('data-value', [value]);, which is secure (as in, the value input is treated as text).
    – tim
    CommentedJun 16, 2020 at 15:28

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.