网络攻击与安全(XSS和CSRF)
XSS(Cross-Site scripting,跨站脚本攻击):
- 一种代码注入式攻击
- 攻击者通过在目标网站上注入恶意脚本,用户浏览时会执行。
- 这种攻击可获取用户的敏感信息如 Cookie、SessionID 等,会话劫持、钓鱼欺骗、强制弹出广告、恶意操作,危害数据安全。
- 是最常见的安全漏洞
本质理解
恶意代码未经过滤,与网站正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。
执行环境在用户终端,恶意代码直接获取用户信息
案例(把输入当成脚本)
某恶意链接
http://xxx/search?keyword="><script>alert('XSS');</script>
当浏览器请求 http://xxx/search?keyword=">alert('XSS');
时,服务端会解析出请求参数 keyword
,得到 ">alert('XSS');
,拼接到 HTML 中返回给浏览器。形成了如下的 HTML:
<input type="text" value=""><script>alert('XSS');</script>">
<button>搜索</button>
<div>
您搜索的关键词是:"><script>alert('XSS');</script>
</div>
而浏览器无法分辨出 alert('XSS');
是恶意代码,于是执行。
注入方式
输入或者引入外部脚本,由浏览器执行,完成复杂的攻击策略
包括
- 在 HTML 中内嵌的文本中以 script 标签形成注入。
- 在内联的 JavaScript 中,拼接的数据突破了原本的限制(字符串,变量,方法名等)。
- 在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签。
- 在标签的 href、src 等属性中,包含
javascript:
等可执行代码。
因此,以下输入内容都”不够安全“
- 来自用户的 UGC 信息
- 来自第三方的链接
- URL 参数
- POST 参数
- Referer (可能来自不可信的来源)
- Cookie (可能来自其他子域注入)
攻击类型
- 反射型 XSS(非持久型):
- 通过 url 的输入,将恶意脚本附加到 url 地址的参数中
- 用户打开带有恶意代码的 url 时,网站服务端将恶意代码从 url 中取出,拼接在 HTML 中返回给浏览器
- 常见于网站搜索、跳转等
- 需要用户手动点击 url,会大力诱导
- 存储型 XSS(持久型):
- 将 XSS 代码发送到服务器,返回的时候会被服务器加载出来,直接执行。
- 常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等,最典型的就是留言板XSS。
类型 | 恶意代码存放位置 | 恶意代码插入点 |
---|---|---|
存储型 XSS | 后端数据库 | HTML |
反射型 XSS | URL | HTML |
预防XSS
- 纯前端渲染,把代码和数据分隔开。
- 对 HTML 做充分转义。
HTTP-only Cookie
: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。- 输入内容长度控制
- 使用验证码,防止脚本冒充用户提交危险操作。
CSRF(Cross-Site Request Forgeries,跨站点请求伪造):
- 通过发起伪造其他网站的请求来实现攻击
- 利用了浏览器对用户身份的保存(cookie),诱导用户在身份有效期内触发请求攻击,发送恶意请求
本质理解
第三方网站中发送跨站请求,获取注册凭证,[冒充]用户进行操作
CSRF攻击者不能获取到Cookie等信息,只是使用
攻击发起在第三方网站,被攻击的网站无法防止攻击发生
是属于跨域的攻击操作
攻击方式
- 用户登录A网站,浏览器自动保存登录cookie
- 用户进入攻击网站B,在B网站的诱导下触发了对A网站的一个请求
- 由于当前 cookie 还在有效期内,所以触发的这个请求被误认为是用户自己发起的请求,被服务器正常处理,造成了攻击
攻击类型
- GET类型的CSRF
打开页面就中招!
只需要一个HTTP请求,一般会这样利用:
<img src="http://bank.example/withdraw?amount=10000&for=hacker" >
在受害者访问含有这个img的页面后,浏览器会自动向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker
发出一次HTTP请求。bank.example
就会收到包含受害者登录信息的一次跨域请求。
- POST类型的CSRF
打开页面就中招!
通常使用的是一个自动提交的表单
<form action="http://bank.example/withdraw" method=POST>
<input type="hidden" name="account" value="xiaoming" />
<input type="hidden" name="amount" value="10000" />
<input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script>
访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作。
- 链接类型的CSRF
用户点击链接才会触发
预防CSRF
CSRF通常从第三方网站发起,被攻击的网站无法防止攻击发生,只能通过增强自己网站针对CSRF的防护能力来提升安全性。
- 设置 cookie 的
sameSite
属性为strict
,让 Cookie 在跨站请求时不会被发送 - 验证
HTTP Referer
字段,验证发起请求的源网址 token
验证- 双重Cookie验证