XSS攻击及防御

XSS:跨站脚本攻击

XSS的危害:

  • 获取页面数据,偷取网站任意数据
  • 获取Cookies,偷取重要用户信息
  • 劫持前端逻辑,破坏网站
  • 发送请求给其他服务器
  • ...等等

造成XSS的原因:

XSS攻击分类:

反射型:一般出现在URL注入和表单输入,经过服务器返回执行

存储型:一般出现在评论之类的需要存储与数据库,然后数据库读取时注入

DOM XSS:与前两者不同的是,它不需要经过服务器,即直接在用户浏览器中输入

XSS攻击注入点,产生的原因,解决办法和相应的实例:

接下来的例子采用node作为服务器,先关闭浏览器的对XSS的默认阻止行为,即设置以下代码

res.set('X-XSS-Protection',0);

1.HTML节点内容

产生的原因:

  • 原来的正常数据会生成
<div>
    正常数据
</div>
  • 那么所注入的脚本就会在浏览器读取到脚本时执行生成
<div>
    <script>...</script>
</div>

解决办法:  对做将‘<’和‘>’转义,分别为 &lt 和 &gt

str = str.replace(/</g, '&lt;')
str = str.replace(/>/g, '&gt;')

实例:

先是html的表单,和服务器的部分代码

 <form action="/upload" method="GET">
    <input type="text" name="name">
    <input type="submit" value='提交'>
  </form>
app.get('/upload', (req, res) => {
    let query = req.query.name
    res.set('X-XSS-Protection',0);    //关闭浏览器的默认阻止XSS行为
    res.writeHead(200,{'Content-Type':'text/html;charset=UTF8'})
    res.write(query)
    res.end()
})

然后在表单输入一串脚本,提交 

然后浏览器就会执行脚本的内容

如果对表单数据进行转义,那么就会输出以下结果,而不是执行脚本

app.get('/upload', (req, res) => {
    let query = req.query.name
    query = query.replace(/</g, '&lt;')
    query = query.replace(/>/g, '&gt;')
    res.set('X-XSS-Protection',0);
    res.writeHead(200,{'Content-Type':'text/html;charset=UTF8'})
    res.write(query)
    res.end()
})

 

2.HTML属性

产生原因:

  • 正常HTML属性
<img src="正常地址" />
  • 属性脚本注入,如下面代码,在src输入一个错误地址,那么就会执行onerror事件,触发后面的脚本
<img src="123" onerror="alert(aaa)" />

解决办法:对双引号,单引号,空格进行转义

          &quot; 是 双引号“ 的转义字符,也可以用十进制&#34;,单引号用十进制&#39;空格的十进制是&#32;

if (!str) return ''
str = str.replace(/"/g, '&#34;')
str = str.replace(/'/g, '&#39;')
str = str.replace(/ /g, '&#32;')  //如何你的属性值都是带引号的,可以不设

实例:

服务器代码

app.get('/', (req, res) => {
    var content = fs.readFileSync('./index.html')
    res.writeHead(200,{'Content-Type':'text/html;charset=UTF8'});
    res.write(content)
    res.end()
})

于是脚本就被执行了 

  

然后进行过滤 

app.get('/upload', (req, res) => {
    let query = req.query.name
    query = query.replace(/"/g, '&#34;')
    query = query.replace(/'/g, '&#39;')
    res.set('X-XSS-Protection',0);
    res.writeHead(200,{'Content-Type':'text/html;charset=UTF8'})
    res.write(query)
    res.end()
})

就不会执行脚本了 ,只是显示图片找不到

3.JavaScript代码

产生原因:

  • 在JavaScript中注入
<script>
    var data = "hello";  //正常脚本
    var data = "hello";alert(1);"";   //被注入的脚本
</script>

 解决办法:对“进行 \ 转义,或者直接使用JSON.stringify()对表单进行处理

if (!str) return ''
str = str.replace(/\\/g, '\\\\')   //一定要放前面
str = str.replace(/"/g, '\\"')

或者直接
JSON.stringify(form)

4.富文本

产生原因:

  • 富文本的内容会被生成HTML形式

解决办法:

   使用白名单:

安装: npm install cheerio
引入: var cheerio = require('cheerio')
var $ = cheerio.load(html)

// 白名单
var whiteList = {
    'img': ['src'],
    'a': ['href']
}
$('*').each(function (index, elem) {
    if (!whiteList[elem.name]) {
        $(elem).remove();
        return;
    }
    for (var attr in elem.attribs) {
       if( whiteList[elem.name].indexOf(attr) === -1) {
            $(elem).attr(attr, null)
        }
    }
})

   使用黑名单:

if (!html) return ''
html = html.replace(/<\s*\/?script\s*>/g, '')
html = html.replace(/javascript:[^'"]*/g, '')
html = html.replace(/onerror\s*=\s*['"]?[^'"]*['"]?/g, '')

使用第三方库

安装: npm install xss
var xss = require("xss");
var html = xss('<script>alert("xss");</script>');

5.使用CSP(内容安全策略)

通过指定有效域,即浏览器认可的可执行脚本的有效来源,使服务器管理者有能力减少或消除XSS攻击所依赖的载体

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP

 

最后:从根源解决,将网站重要的用户信息进行加密,给Cookie设置HttpOnly属性,这样就不能通过document.cookie来访问Cookie了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值