Recently I've met the XSS problem. I've searched and read a lot of related questions and articles. I've noticed that all answers are focused on how to prevent untrusted data to be passed to server. And in front-end, escape special codes seems the only way to prevent scripts execute.
But what if a user just input a piece of code(such as <script>alert("hi");</script>
) to an input, when will this code executes? And is there a way to prevent it?
I've listened the keydown
keyup
event, but this can only prevent normal input, it has no effort when user copy and paste directly into input, it'll show my warning message when user input a piece of script, but the script still executed!
$("input").on("keyup", function (e) {
var value = $(this).val() || "";
var regex = /<(\/?\w+[^\n>]*\/?)>/ig;
if(regex.test(value)){
layer.msg("Invalid characters!");
$(this).val(value.replace(regex, "<$1>"));
e.preventDefault();
return false;
}
});
I don't understand why the script in an input's value is executed by browser, and when it is executed ? Is there any articles that can explain this mechanism or is related ? Did I have something unnoticed ? If there any articles that you think will help, please let me know. Thanks.
Thanks for all the answers and comments. Maybe I didn't describe it clear. I've test that when I copied <script>alert("hi");</script>
and paste it into an input, the browser did prompt an alert window and showed the "hi".
I've also just use $("input").val('<script>alert("hi");</script>')
, it won't prompt alert window, but if I trigger the input's focus
and blur
event, it will prompt the alert window too.
So, why the codes are executed ?
Say my user name was <script>alert('You got pranked!')</script>
and your app isn't protected against XSS.
When registering, the app will save my user name as is, and there's nothing wrong with that.
But, when I go to my profile page (or any page that will display my name), the HTML rendered by the server will look like that
<h1>Profile page</h1>
<p>User name: <script>alert('You got pranked!')</script></p>
The client browser will see a <script>
tag and will execute what is inside.
The easiest solution to counter that is to escape any HTML-special characters. No matter what tech stack you have, there are lots of tools that will do that for you.
But the way all these tools work, is that when displaying my user name, it will be shown as <script>alert('You got pranked!')</script>
, thus preventing the browser from seeing a <script>
tag when displaying my user name.
The value or contents of form fields are not executed by browsers, nor are they parsed as HTML unless you treat them as HTML.
You can paste anything you like into an input field, and submit it to a server. Pasting <script>alert("hi");</script>
into an input is fine, and that text will be used as the value of the input field when the form data is submitted to the server.
The problem of XSS comes when a site uses previously submitted data and squirts it into the HTML of a response (as described in RichouHunter's answer)
An example of treating the input field as HTML without going to the server:
// Assuming jQuery:
$('div').html($('input').val());
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