XSS攻击
什么是XSS
Cross-Site Scripting【跨站脚本攻击】简称XSS,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上面运行,利用这些脚本,攻击者可以获取用户的敏感信息,比如Cookies,SessionID等,进而危害数据安全
XSS本质
XSS 的本质是:恶意代码未经过滤,与网站正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。
XSS的分类
存储型、反射型、DOM型
存储型XSS
- 将恶意代码提交到目标网站的数据库中
- 用户打开网站时,恶意代码被数据库取出,渲染到页面被拼接
- 用户接收到响应后解析执行,混在其中的恶意代码也被执行
- 窃取用户数据,此时就可冒充用户
这种攻击常见于带有用户保存数据的网站功能,比如论坛,评论和私信
一个例子:
1 | <input type="text" value="“> |
反射型XSS
- 攻击者构造出特殊的URL,其中包含恶意代码
- 用户打开带有恶意代码的URL时,网站服务端会将恶意代码从URL中取出,拼接在HTML中返回给浏览器
- 用户浏览器收到响应后转义HTML,此时恶意代码也被混入
- 恶意代码此时会窃取用户数据
这种攻击常见于网站搜索和跳转链接中
由于需要用户主动打开恶意的URL才能生效,攻击者会结合多种手段诱导点击
POST内容也可以触发反射型XSS,不过条件苛刻
一个例子:
1 | <!-- 攻击者设计的诱导链接 --> |
DOM型XSS
- 攻击者构造出特殊的URL,其中包含恶意代码
- 用户打开带有恶意代码的URL
- 用户浏览器接收到响应后解析执行,前端JS取出URL中的恶意代码并执行
- 恶意代码此时会窃取用户数据
DOM型的XSS和前面两种XSS的区别:DOM型XSS攻击中,取出和执行恶意代码由浏览器端完成,属于前端JS自身的安全漏洞,而其他两种属于服务器端的安全漏洞
注意事项
在使用
.innerHTML
、.outerHTML
、document.write()
时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用.textContent
、.setAttribute()
等。如果用 Vue/React 技术栈,并且不使用
v-html
/dangerouslySetInnerHTML
功能,就在前端 render 阶段避免innerHTML
、outerHTML
的 XSS 隐患。
通常的注入方法
在 HTML 中内嵌的文本中,恶意内容以 script 标签形成注入。
在内联的 JavaScript 中,拼接的数据突破了原本的限制(字符串,变量,方法名等)。
在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签。
在标签的 href、src 等属性中,包含
javascript:
等可执行代码。在 onload、onerror、onclick 等事件中,注入不受控制代码。
在 style 属性和标签中,包含类似
background-image:url("javascript:...");
的代码(新版本浏览器已经可以防范)。在 style 属性和标签中,包含类似
expression(...)
的 CSS 表达式代码(新版本浏览器已经可以防范)。
一些措施
- CSP
- 输入内容长度控制【不能完全阻止XSS注入,但能增加难度】
- HTTP-only Cookie: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。
- 验证码:防止脚本冒充用户提交危险操作。
CSRF攻击
什么是CSRF
CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的
攻击流程
- 受害者登录着a.com,并且保留着登录凭证Cookies
- 攻击者诱导受害者访问b.com
- b.com对a.com发送请求:a.com/act=xx
- a.com接收请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者发出的请求
- a.com以受害者的名义执行了act=xx
- 攻击完成,以窃取用户登录信息
CSRF分类
GET类型
较为简单,只需要一个HTTP请求
1 | <img src="http://bank.example/withdraw?amount=10000&for=hacker" > |
受害者访问到了带有这个图片的页面后,浏览器会自动向http://bank.example/withdraw?amount=10000&for=hacker
发出一次HTTP请求,bank.example
就会收到包含受害者登录信息的一次跨域请求
POST类型
通常使用表单,自动获取用户数据并自动提交用户敏感信息
1 | <form action="http://bank.example/withdraw" method=POST> |
访问该页面后,就会提交表单【与此同时你根本看不到这些元素,不知道信息被窃取】
因此后端接口不能将安全寄托在仅允许POST上面
链接类型
需要用户点击恶意链接、恶意图片才会触发
1 | <img> |
由于用户登录了信任的网站A,并且保存登录状态,只要用户点击主动访问上面的页面,则表示攻击成功
CSRF攻击特点
- 攻击一般发起在第三方网站,因此被攻击的网站无法防止攻击发生
- 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作,而并非直接窃取数据
- 整个过程攻击者并不能获取到受害者的登录凭证,而只是冒用
- 跨站请求可以使用各种方式,比如图片URL,超链接,CORS,Form提交等。部分请求方式可以直接嵌入在第三方的论坛和文章中,难以进行追踪
CSRF通常为跨域的,因为外域更容易被攻击者掌控;但是本域下有容易被利用的功能,比如可以发图片链接,则攻击可以直接在本域下进行,并且攻击更加危险。
攻击者无法直接窃取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用Cookie中的信息。
防护策略
只能增加自己网站针对CSRF的防护能力和本域CSRF攻击的预防能力
增加防护能力
- 阻止不明外域的访问
- 同源检测
- Samesite Cookies
- 提交时要求附加本域才能获取的信息
- CSRF Token
- 双重Cookies验证:要求AJAX和表单请求携带一个Cookies【这个Cookies用来安全认证,另一个用来保存个人信息】
增加预防能力
- 严格管理所有的上传接口,防止任何预期之外的上传内容
- 添加Header
X-Content-Type-Options: nosniff
防止黑客上传HTML内容的资源被解析成网页 - 对于用户上传的图片进行转存或者校验,不要直接使用用户填写的图片链接
- 打开其他链接时,提前告知打开有风险
SSRF攻击
定义
SSRF,被称为:服务器端伪造请求
例子
下面为例子:
1 | public async convertVideo (ctx) { |
攻击者可以在options
中传入:
1 | fetch ('/api', { |
这样就执行了rm -rf
,十分可怕,对服务器的文件进行删除!
当然,还有其他的攻击,比如暴露文件,或者更改代理去流量攻击目标网站
解决方案
- 最小权限原则,不允许给root权限
- 对每一个用户给一个相应白名单
- 对URL类型参数进行协议、域名、ip限制
DoS攻击
定义
通过某种方式【构造特定请求】,导致服务器资源被显著消耗,来不及响应更多请求,导致请求挤压造成雪崩效应
一些攻击方法
ReDoS:基于正则表达式的DoS
利用了正则表达式的贪心匹配,进行大规模数据试错,服务器不能及时完成全部请求,导致请求堆积进而崩溃
DDoS
短时间内,来自大量僵尸设备的请求浏览,服务器不能及时完成全部请求,导致请求堆积进而崩溃
攻击特点:
- 直接访问IP
- 任意API
- 消耗大量带宽【通常都耗尽了】
解决方法
Regex DoS
- 代码检查,不允许贪婪匹配
- 代码扫描并做正则性能测试
- 不允许使用用户提供的正则
DDoS
- 过滤
- 负载均衡
- API网关
- 抗量
- CDN证书
- 快速自动扩容
- 非核心服务降级
中间人攻击
定义
在浏览器和服务器之间有一个中间人,每次浏览器和服务器交互数据,都会经过中间人,中间人可以获取隐私信息,甚至是传输恶意信息
一般特点
- 明文传输
- 信息篡改不可知
- 对方身份未验证
措施
- 使用数字签名【加密】
- CA证书等
- 将HTTP升级为HTTPS协议