# 一、为什么XMLHttpRequest不能跨域
# 1.什么是同源策略?
- 同协议,同域名,同端口就是同源策略。
# 二、XSS攻击——跨站脚本
概念:指黑客往HTML文件中或者DOM中注入恶意脚本,从而在用户浏览页面时利用注入的恶意脚本对用户实施攻击。一开始是通过跨域进行攻击,但是现在通过往HTML文件中注入恶意代码的方式很多,所以跨域注入脚本已经不是唯一注入手段。
XSS 翻译过来是,跨站脚本。早期是通过跨域的方式进行攻击。后来注入恶意代码的方式比较多。因为浏览器无法识别是恶意脚本,所以恶意脚本有着普通脚本的所有权限。
# 恶意脚本可以干什么?
1.窃取Cooike信息
恶意JS可以通过 document.cooike 获取cookie信息,然后通过XMLHttpRequest或者Fetch加上CORS功能将数据发送给恶意服务器,拿到信息后就可以模拟用户登录,进行转账等操作。
2.监听用户行为
JS可以通过 addEventlistener 接口监听键盘事件,输入账号密码等操作完全被监听。
3.恶意广告
# 怎么注入恶意脚本
1.存储型XSS攻击
将恶意脚本存入存在漏洞的服务器,用户去访问这个页面的服务器,然后可以通过脚本获取信息,再上传到攻击者的服务器。
2.反射型XSS攻击
就是用户在点击QQ邮箱等恶意链接的时候,将恶意脚本嵌入请求中,用户就会把恶意脚本提交到服务器上,服务器接收到又会反射给浏览器端。
因web端不会存储恶意脚本,所以这是和存储型攻击的区别。
3.基于DOM的XSS攻击
这种攻击方式是不需要涉及服务器的,黑客通过各种手段将恶意脚本注入用户的页面,在HTML传输过程中劫持并修改HTML的内容。 WiFi路由劫持,本地恶意软件
# 如何阻止XSS攻击
存储型攻击和反射型攻击都需要经过服务器,所以可以认为这是服务器漏洞型。
而 基于DOM的XSS攻击是在浏览器端发生的,因此基于DOM的XSS攻击时前端的漏洞。
以上三者的共同点都是注入恶意脚本,所以可以考虑阻止恶意脚本的注入和恶意消息的发送来实现。
1.服务器对输入脚本进行过滤或转码
尽量的将 script标签给过滤 或者转码,转码就不会执行。
<script>
2.充分利用SCP
虽然转码可以阻止XSS攻击,但这是完全依赖服务端的。充分利用SCP可以降低XSS攻击带来的风险和后果。
SCP有以下功能:
1.限制下载其他域资源,就算黑客插入JS文件,也无法加载。
2.禁止向第三方提交数据,用户数据不会外泄。
3.禁止执行内联脚本和未授权的脚本。
4.有上报功能。
# 3.开启httpOnly为true
- 如果这个属性设置为true,就不能通过js脚本来获取cookie的值,能有效的防止xss攻击
# 三、CSRF攻击——跨站请求伪造
简单的例子:
1.小明发起登录邮箱请求,服务器返回登录状态给小明的浏览器,这些信息包括Cookie,Session等信息,这样小明的浏览器就处于登录状态了。
2.黑客引诱小明点击恶意链接,比如hacker.com,黑客在里面编写好一个邮件过滤器,通过Gmail提供的HTTP设置接口设置好了新的邮件过滤功能,该过滤器会将小明所有的邮件转发到黑客邮箱。
# 1.什么是CSRF
指的是黑客引诱用户打开黑客的网站,在黑客网站中,利用用户的登录状态发起的跨站请求。
概括:CSRF攻击时黑客利用用户的登录状态,利用第三方站点做一些坏事。
# 2.CSRF攻击方式
下面是一个转账的接口
# 同时支持 POST 和 Get
# 接口 https://time.geekbang.org/sendcoin
# 参数
## 目标用户
user
## 目标金额
number
有了上面转账接口,就可以模拟CSRF攻击了
1.自动发起Get请求
- 属于最容易的攻击方式
- 黑客将转账请求接口隐藏在img标签内,欺骗浏览器这是一张图片,页面被加载,发起img资源请求,服务器没判断的话,服务器就会认为该转账请求时一个转账请求,于是用户的钱就被转走了
<!DOCTYPE html>
<html>
<body>
<h1> 黑客的站点:CSRF 攻击演示 </h1>
<img src="https://time.geekbang.org/sendcoin?user=hacker&number=100">
</body>
</html>
2.自动发起POST请求
除了自动发送Get请求之外,有些服务器接口是使用POST方法的,所以黑客需要在他的站点上伪造POST请求,当用户打开黑客的站点时,是自动提交POST请求。具体代码如下
- 这段代码中,黑客在他的页面中构建了一个隐藏的表单,该表单内容就是转账接口。用户打开后就会被自动提交,进行转账,因此使用构建自动提交 表单这种方式,就可以自动实现跨站点POST数据提交。
<!DOCTYPE html>
<html>
<body>
<h1> 黑客的站点:CSRF 攻击演示 </h1>
<form id='hacker-form' action="https://time.geekbang.org/sendcoin" method=POST>
<input type="hidden" name="user" value="hacker" />
<input type="hidden" name="number" value="100" /> </form>
<script> document.getElementById('hacker-form').submit(); </script>
</body>
</html>
3.引诱用户点击链接
引诱用户点击黑客站点上的链接,着这种方式通常出现在论坛或者恶意邮件上。
例如:一个a标签上是点击下载美女照片,实际上href是一个转账接口,点了就完蛋。
# 3.如何防止CSRF
1.利用好Cookie的SameSite属性
因为CSRF是依靠登录态发起攻击的,Cookie是浏览器和服务器之间维护登录状态的一个关键数据。
CSRF是通过第三方站点发起的,从第三方站点禁止Cookie的发送。所以在浏览器通过不同来源发送HTTP请求,主要有一下区别:
1.从第三方站点发送请求,则禁止浏览器发送某些关键的Cookie数据到服务器上。
2.如果是同一个站点发起的请求,就需要保证Cookie数据正常发送。
在HTTP响应头中,通过set-cookie字段设置Cookie时,可以带上SameSite选项。
2.验证请求的来源站点
在服务端验证请求来源的站点,csrf大多数来自第三方站点,禁止第三方站点可以降低攻击概率。
如何判断第三方站点:
请求头中的Referer字段可以判断请求来源站点的,但是浏览器有些时候直接暴露url是不合适的,这个时候又可以使用origin属性,XMLHttpRequest、Fecth 发起跨站请求或者通过 Post 方法发送请求时,都会带上 Origin 属性。
c3.CSRF Token
这个流程有两步:
1.浏览器发起请求时,生成csrf token,服务生成的简单字符串,再将字符串植入返回的页面中。input value="dawdawd13ds"
2.在浏览器端发起转账请求的话,需要带上token,服务器验证token是否合法,第三方肯定是无法获取token的,所以无法发起请求。