最近我遇到了XSS问题。我搜索并阅读了很多相关的问题和文章。我注意到所有答案都集中在如何防止不受信任的数据传递给服务器。在前端,转义特殊代码似乎是防止脚本执行的唯一方法。
但是如果用户只是输入一段代码(例如<script>alert("hi");</script>
)到输入,该代码何时执行呢?有没有办法防止它?
我已经收听了keydown
keyup
事件,但这只能阻止正常输入,当用户复制并直接粘贴到输入时它不费力,它会在用户显示我的警告消息输入一段脚本,但脚本仍然执行!
$("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;
}
});
我不明白为什么输入值中的脚本是由浏览器执行的,以及何时执行?是否有任何文章可以解释这种机制或相关?我有什么不被注意的东西吗? 如果有任何您认为有帮助的文章,请告诉我。 感谢。
感谢所有的答案和评论。也许我没有说清楚。当我复制<script>alert("hi");</script>
并将其粘贴到输入中时,我测试了,浏览器确实提示了一个警告窗口并显示“hi”。
我也只是使用$("input").val('<script>alert("hi");</script>')
,它不会提示警报窗口,但如果我触发输入的focus
和blur
事件,它也会提示警报窗口。
那么,代码执行的原因是什么?
答案 0 :(得分:2)
假设我的用户名为<script>alert('You got pranked!')</script>
,您的应用不受XSS保护。
注册时,应用程序会保存我的用户名,并且没有任何问题。
但是,当我转到我的个人资料页面(或任何会显示我姓名的页面)时,服务器呈现的HTML将会是这样的
<h1>Profile page</h1>
<p>User name: <script>alert('You got pranked!')</script></p>
客户端浏览器将看到<script>
标记,并将执行内部的内容。
最简单的解决方法是逃避任何HTML特殊字符。无论你有什么技术堆栈,都有很多工具可以帮到你。
但所有这些工具的工作方式是,在显示我的用户名时,它会显示为<script>alert('You got pranked!')</script>
,从而阻止浏览器在显示我的用户名时看到<script>
标记。 / p>
答案 1 :(得分:2)
表单字段的值或内容不由浏览器执行,也不会被解析为HTML ,除非您将它们视为HTML 。
您可以将任何您喜欢的内容粘贴到输入字段中,然后将其提交给服务器。将<script>alert("hi");</script>
粘贴到输入中很好,当表单数据提交给服务器时,该文本将用作输入字段的值。
当网站使用以前提交的数据并将其喷射到响应的HTML中时(如RichouHunter's answer中所述),就会出现XSS问题
将输入字段视为HTML 而不进入服务器的示例:
// Assuming jQuery:
$('div').html($('input').val());