html() vs innerHTML jquery/javascript & XSS attacks

Contrary to what is being said in the accepted answer, jQuery.html() and the many jQuery functions which accept HTML strings as arguments are more prone to DOM-based XSS injection than innerHTML, as noticed by the OP.

jQuery.html() extracts the <script> tags, updates the DOM and evaluates the code embedded in the script tags.

As a result, XSS can happen without user interaction even after the DOM is loaded when using jQuery.html().

This is very easy to demonstrate.

This will call alert():

$('.xss').html('<script>alert("XSS");</script\>');

http://jsfiddle.net/2TpHC/

While this will not:

var d = document.getElementById('xss');
d.innerHTML = '<script\>alert("XSS");</script\>';

http://jsfiddle.net/Tjspu/

Unfortunately, there are many other code paths (sinks) which lead to calling eval() in jQuery. The security conscious will probably avoid jQuery altogether, as far as possible.

Note that I do not claim that using innerHTML is an effective defense against XSS. It is not. Passing unescaped data to innerHTML is not safe, as pointed out by @daghan. One should always properly escape data when generating HTML.

Leave a Comment