XSS定义
跨站脚本攻击(XSS)是指攻击者通过在网页中注入恶意脚本 srcipt ,进而在用户浏览该网页时执行恶意脚本
,从而窃取用户信息、篡改网页内容等。总之:安全无小事,需要前后端等同学都预防,默认不信任数据
。
不安全的数据来源
- 假设来源不一定安全,那么需要进行转义。
- URL查询参数
- 后台数据库(接口)返回值
- 用户在当前页面的输入内容
- 假设来源安全(内存临时变量),那么大概率安全,也要进行判断。
一、HTML相关
1、避免使用.innerHTML
和 .outerHTML
当从URL查询参数中取值并未经过转义处理直接使用时,攻击者可以在URL中添加恶意脚本,使其在用户访问时被执行。
html
<div id="content"></div>
<script>
var content = document.getElementById("content");
var name = new URLSearchParams(window.location.search).get("name");
content.innerHTML = "Hello, " + name;
// 解决办法:使用`.innerText`或`.textContent`替代`.innerHTML`和`.outerHTML` 或者其他转义方法
</script>
1.2 解释
在上述代码中,从URL查询参数中获取name
值,并直接将其插入到页面中,未经过转义处理。攻击者可以在URL中添加恶意脚本,例如:?name=<script>alert('XSS')</script>
,当用户访问该URL时,恶意脚本将被执行。
2、避免使用document.write()
避免使用document.write()
,改用其他DOM操作方法,如createElement
、appendChild
等。
html
<div id="content"></div>
<script>
var content = document.getElementById("content");
var userInput = "<script>alert('XSS');</script>";
// 错误写法 document.write(userInput);
var textNode = document.createTextNode(userInput);
content.appendChild(textNode);
</script>
3、使用.setAttribute()
前要判断
当使用.setAttribute()
为元素设置属性时,确保属性值不包含恶意脚本
html
<a id="link" href="#">Click me</a>
<script>
var link = document.getElementById("link");
var userInput = "javascript:alert('XSS');";
// 错误写法 link.setAttribute("href", userInput);
if (!/^javascript:/i.test(userInput)) {
link.setAttribute("href", userInput);
}
</script>
4、使用Vue.js中的v-html
之前要判断
Vue.js中避免使用v-html
指令插入不可信的动态内容。如有必要,可以使用第三方库(如DOMPurify)对内容进行清理。
html
<div id="app">
<div v-html="cleanedUserInput"></div>
</div>
<script>
new Vue({
el: "#app",
computed: {
cleanedUserInput: function() {
return DOMPurify.sanitize(this.userInput);
}
},
data: {
userInput: "<script>alert('XSS');</script>"
}
});
</script>
二、JavaScript相关
eval()
、setTimeout()
和setInterval()
都可以执行JavaScript代码,当这些函数的参数是用户可控的输入时,可能会引入安全风险,尤其是跨站脚本攻击(XSS)。
1. eval()
javascript
var userInput = "alert('XSS');";
// 错误写法 eval(userInput);
避免使用`eval()`,尽量使用其他安全的方法来实现需求
2.setTimeout()
javascript
var userInput = "alert('XSS');";
// 错误写法 setTimeout(userInput, 1000);
解决办法:使用函数作为`setTimeout()`的第一个参数,而不是字符串。
setTimeout(function() {
alert('Safe code');
}, 1000);
3.setInterval()
与 setTimeout() 相同
三、与后台相关
对用户提交的数据进行过滤和转义。示例:攻击者在评论系统中提交带有恶意脚本的评论,例如<script>alert('XSS');</script>
,当其他用户查看评论时,恶意脚本被执行。 解决办法:在存储用户提交的数据之前,对其进行过滤和转义。可以使用专门的转义函数或库,如escapeHTML()
、DOMPurify
等。另外如果数据库被恶意写入数据,那么也会导致前端不安全。
四、第三方库和插件
示例:使用了一个存在XSS漏洞的富文本编辑器。 解决办法:使用安全的第三方库和插件
,并确保及时更新以修复已知漏洞。