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\>');
While this will not:
var d = document.getElementById('xss');
d.innerHTML = '<script\>alert("XSS");</script\>';
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.