前端安全问题之-----XSS
各行各业“安全”问题都是一个很大的话题,在IT
中我们可以把安全问题按照发生的区域分,可以分为后端安全问题和前端安全问题,作为一名前端开发,这篇文章我们就先来总结一哈给前端有关的安全问题咯。
-
XSS
攻击 又叫跨站脚本攻击,主要是通过用户输入或者其他方式,来向我们的程序中注入一些带有危险行为的代码,一旦我们没有很强的防御意识,去执行了这段危险代码,我们的程序就会受到相应的攻击
常见的有:
- 留言板/富文本(持久性攻击)
- 通过修改
URL
参数的方式加入攻击代码http://www.xsstext.com?info=<script>alert(document.cookie)</script>
(非持久),这种方式一般浏览器会自动帮助用户防御攻击,因此本文不讲啦,有兴趣的小伙伴自己查阅资料咯
为了直观的体会这个XSS
持久性攻击,下面我写了一个简易的留言板功能
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>无标题文档</title>
<style>
.record{
width: 600px;
min-height: 400px;
border-radius: 8px;
background-color: #e99e83;
text-align: center;
}
#msg{
border: 1px solid pink;
border-radius: 10px;
width: 500px;
}
#msg_c{
margin: 0 auto;
background-color: #fff;
width: 560px;
min-height: 200px;
}
#btn{
width: 360px;
background-color: #eb5f5f;
font-size: 12px;
border-radius: 3px;
}
li {
color: 14px;
color: #4dec4d;
text-align: left;
}
li > span{
color: red;
cursor: pointer;
margin-left: 30px;
}
</style>
<script>
window.onload = function(){
var oMsg = document.getElementById("msg");
var oBtn = document.getElementById("btn");
var oMsg_c = document.getElementById("msg_c");
var oUl = document.createElement("ul");
oMsg_c.appendChild(oUl);
oBtn.onclick = function(){
var sVal = oMsg.value;
var oli = document.createElement("li");
oli.innerHTML = sVal;
var oli1 = oUl.getElementsByTagName("li")
if(oli1.length>0){
oUl.insertBefore(oli,oli1[0])
}else{
oUl.appendChild(oli);
}
oMsg.value='';
}
}
</script>
</head>
<body>
<div class="record">
<h3>留言板</h3>
<textarea id="msg" type="text" size="40" value=""></textarea> <br />
<input id="btn" type="button" value="留言">
<div id="msg_c"></div>
</div>
</body>
</html>
效果图如下:
当我们尝试着在留言区域输入诸如<img src="404.html" onerror="alert(110)" />
这样的代码,当我们点击留言按钮时候,会弹出一个框里面展示着我们110
试想一下当一些不怀好意的人利用这种留言板的漏洞,在留言区域把以上的代码改成<img src="404.html" onerror="alert(document.cookie)" />
那么一些储存在cookie
里面的一些比较隐私的信息是不是就暴露了,如果cookie
里面存储的正好是一些诸如银行登录账户信息,那么这种危害就是巨大的
那么既然存在这样的危害,我们应该怎么来降低这样的风险呢?
- 第一:做一些字符转换措施,比如
html
的encode
和js
的encode
// html的转换
// 就是将一些有特殊意义的字符串进行替换
& => &
" => "
' => '
< => <
> => >
<img src="404.html" onerror="alert(110)"> 就被html/encode特殊转化---> <img src="404.html" onerror="alert(110)">
// js的转换
// 使用“\”对特殊字符进行转义,除数字字母之外,小于127的字符编码使用16进制“\xHH”的方式进行编码,大于用unicode
var arr = [1,2,3,4,6,7,8,9,10,11,12,13,14,15] 就被js/encode特殊转化----> var arr = [1,2,3,4,6,7,8,9,'a','b','c','d','e','f']
- 第二:对于像富文本这样的做一些诸如白名单过滤措施
由于富文本是比较特殊的,因为我们输入的标签比如加粗倾斜等等我们是希望表现出来的,因此不能用第一种方式解决,所以我们就需要用一份白名单来限定哪些标签以及属性是相对合法的,不会有XSS
攻击的风险,相当于在白名单之中的标签和属性有了一个通行证,在输入提交富文本的时候不会被过滤掉
// 假设我们的代码中用了一个(白名单.js)库来过滤一些不合法的标签以及属性那么之前用户输入文本框的代码会变成
<img src="404.html" onerror="alert(document.cookie)"> 就被过滤成---> <img src="404.html">
最后留一个思考题:你们认为这种白名单过滤和js/html--encode
是在客户端我们用户提交的时候做还是保存到了服务器在做呢服?(提示一下小伙伴可以朝多端展示方向考虑哦),有答案的欢迎留言哦😺