jQuery html() method a security risk like innerHTML?
From the JQuery documentation:
Additional Notes:
By design, any jQuery constructor or method that accepts an HTML string — jQuery(), .append(), .after(), etc. — can potentially execute code. This can occur by injection of script tags or use of HTML attributes that execute code (for example, ). Do not use these methods to insert strings obtained from untrusted sources such as URL query parameters, cookies, or form inputs. Doing so can introduce cross-site-scripting (XSS) vulnerabilities. Remove or escape any user input before adding content to the document.
So, for example, if the user were to pass an HTML string that contains a <script>
element, then that script would be executed:
$("#input").focus();
$("#input").on("blur", function(){
$("#output").html($("#input").val());
});
textarea { width:300px; height: 100px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="input"><script>alert("The HTML in this element contains a script element that was processed! What if the script contained malicious content?!")</script></textarea>
<div id="output">Press TAB</div>
But, if we escape the string's contents before we pass it, we're safer:
$("#input").focus();
$("#input").on("blur", function(){
$("#output").html($("#input").val().replace("<", "<").replace(">", ">"));
});
textarea { width:300px; height: 100px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="input"><script>alert("This time the < and > characters (which signify an HTML tag are escaped into their HTML entity codes, so they won't be processed as HTML.")</script></textarea>
<div id="output">Press TAB</div>
Finally, the best way to avoid processing a string as HTML is not to pass it to .innerHTML
or .html()
in the first place. That's why we have .textContent
and .text()
- they do the escaping for us:
$("#input").focus();
$("#input").on("blur", function(){
// Using .text() escapes the HTML automatically
$("#output").text($("#input").val());
});
textarea { width:300px; height: 100px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="input"><script>alert("This time nothing will be processed as HTML.")</script></textarea>
<div id="output">Press TAB</div>