I recently was reading a JavaScript book and discovered using innerHTML to pass plain text poses a security risk, so I was wondering does using the html()
jQuery method pose these same risks? I tried to research it but I could not find anything.
For Example:
$("#saveContact").html("Save"); //change text to Save
var saveContact = document.getElementById("saveContact");
saveContact.innerHTML = "Save"; //change text to Save
These do the same thing from what I know, but do they both pose the same security risk of someone being able to inject some JavaScript and execute it?
I am not very knowledgeable in security, so I apologize in advance if anything is incorrect or explained incorrectly.
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>
From the .html()
docs:
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.
This is why .innerHTML
is bad and why .html()
is also not good to use on strings from untrusted sources, say if you make an ajax request to get some data from an untrusted third party. You should use one of the numerous methods here or better still, a proven library function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With