🤍 前端开发工程师、技术日更博主、已过CET6
🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1
🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》
🍚 蓝桥云课签约作者、上架课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》
💬 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
文章目录
- 一、定义与原理
- 二、CSRF攻击的类型
- (一)GET类型CSRF
- (二)POST类型CSRF
- 三、防范措施
- (一)验证请求来源(Same - Origin Policy)
- (二)使用CSRF令牌(Token)
- (三)设置合适的安全策略和HTTP头
一、定义与原理
- 概念
- CSRF(Cross - Site Request Forgery),即跨站请求伪造,是一种网络安全攻击方式。攻击者利用用户在目标网站的登录状态,通过诱使受害者访问恶意页面或者点击恶意链接,在受害者不知情的情况下,让受害者的浏览器向目标网站发送请求,这些请求可能会执行一些对攻击者有利但对用户有害的操作,如修改用户信息、进行转账等。
- 攻击原理
- 大多数网站在用户登录后会建立一个会话(Session),并通过Cookie或者其他方式来识别用户身份。当用户访问一个被攻击者控制的恶意页面时,这个页面中的恶意脚本可以构造一个请求,该请求会自动携带用户浏览器中的目标网站的身份识别信息(如Cookie),并将请求发送到目标网站。由于目标网站无法区分这个请求是用户正常操作还是被伪造的请求,就可能会执行这个请求中的操作。
二、CSRF攻击的类型
(一)GET类型CSRF
- 原理与过程
- GET类型的CSRF攻击主要利用了HTML中
<img>
、<a>
等标签可以自动发送GET请求的特性。攻击者在恶意页面中嵌入一个<img>
标签,其src
属性指向目标网站的一个会产生副作用的URL(如修改密码的URL)。当受害者的浏览器加载这个恶意页面时,会自动发送这个GET请求,从而可能导致目标网站执行相应的操作。 - 例如,目标网站有一个修改用户密码的接口
http://example.com/change - password?newpassword = 123456
,攻击者在恶意页面中插入<img src="http://example.com/change - password?newpassword = 123456" alt=""/>
。当用户访问这个恶意页面时,浏览器会自动发送一个修改密码的GET请求,而用户可能完全不知情。
- GET类型的CSRF攻击主要利用了HTML中
- 攻击场景与影响
- GET类型的CSRF攻击相对比较容易被发现,因为它通常会在浏览器的历史记录或者服务器日志中留下痕迹。但是,如果目标网站没有对敏感操作进行适当的保护,这种攻击仍然可能会导致用户信息泄露或者数据被篡改。这种攻击在一些旧的或者安全性较低的网站中比较常见。
(二)POST类型CSRF
- 原理与过程
- POST类型的CSRF攻击通常需要借助JavaScript来构造一个伪造的表单并自动提交。攻击者在恶意页面中创建一个包含目标网站操作的表单,如转账表单,然后通过JavaScript自动提交这个表单。当受害者访问恶意页面时,浏览器会在用户不知情的情况下发送这个POST请求,就好像用户自己在目标网站上执行了这个操作一样。
- 例如,攻击者在恶意页面中添加以下代码:
<form id="csrf - form" action="http://example.com/transfer - money" method="POST"><input type="hidden" name="amount" value="10000" /><input type="hidden" name="recipient" value="attacker - account" /> </form> <script>document.getElementById('csrf - form').submit();</script>
- 当用户访问这个恶意页面时,会自动向目标网站发送一个转账10000元到攻击者账户的POST请求。
- 攻击场景与影响
- POST类型的CSRF攻击比GET类型更具隐蔽性,因为POST请求通常用于提交表单等操作,在服务器日志中看起来可能更像是用户的正常操作。这种攻击可能会导致严重的经济损失或者数据泄露,尤其是在涉及金融交易或者敏感信息修改的网站上。
三、防范措施
(一)验证请求来源(Same - Origin Policy)
-
同源策略原理
- 浏览器的同源策略是一种重要的安全机制。它规定,只有当两个页面的协议、域名和端口都相同(即同源)时,一个页面中的脚本才能访问另一个页面的资源。在防范CSRF攻击时,可以利用同源策略来验证请求是否来自合法的来源。
- 例如,如果一个请求是从与目标网站不同源的页面发出的,浏览器会阻止这个请求访问目标网站的敏感资源,除非目标网站明确允许跨源访问(通过CORS等机制)。
-
验证方法与局限性
- 可以通过检查请求头中的
Referer
(注意拼写是Referer,不是Reference)或者Origin
字段来验证请求的来源。Referer
字段包含了请求的来源页面的URL,Origin
字段只包含了来源的协议、域名和端口。 - 然而,这些方法都有一定的局限性。
Referer
字段可能会被浏览器或者用户代理(User - Agent)修改或者隐藏,Origin
字段在一些跨域场景下可能不存在或者不准确。并且,一些较老的浏览器可能不支持这些字段的验证。
- 可以通过检查请求头中的
(二)使用CSRF令牌(Token)
- 令牌生成与存储
- CSRF令牌是一种防范CSRF攻击的有效方法。网站在生成页面时,会为每个用户会话或者每个重要的表单生成一个唯一的令牌(Token),并将这个令牌存储在用户的会话(如服务器端的Session)中,同时将令牌以隐藏表单元素或者请求头的方式发送给用户浏览器。
- 例如,在一个使用Python的Django框架的网站中,当生成一个表单时,可以使用Django的内置功能来生成和存储CSRF令牌:
from django.shortcuts import render from django.views.decorators.csrf import csrf_protect@csrf_protect def my_view(request):if request.method == 'POST':# 验证CSRF令牌if request.POST.get('csrfmiddlewaretoken') == request.session.get('csrfmiddlewaretoken'):# 执行正常的表单操作passelse:request.session['csrfmiddlewaretoken'] = generate_csrf_token()return render(request, 'my - template.html')
- 令牌验证过程
- 当用户提交表单或者发送请求时,网站会验证请求中携带的CSRF令牌是否与存储在用户会话中的令牌一致。如果令牌不一致或者不存在,就拒绝这个请求,认为可能是一个CSRF攻击。这种方法可以有效地防止攻击者伪造请求,因为攻击者很难获取到合法的CSRF令牌。
(三)设置合适的安全策略和HTTP头
- Same - Site Cookie属性
- 可以通过设置Cookie的
Same - Site
属性来增强对CSRF攻击的防范。Same - Site
属性有三个值:Strict
、Lax
和None
。 - Strict:当设置为
Strict
时,浏览器只会在请求来自与设置Cookie的网站完全相同的网站(同源)时,才会发送这个Cookie。这可以有效地防止CSRF攻击,但可能会对一些合法的跨站操作(如通过链接从其他网站跳转到目标网站)产生影响。 - Lax:
Lax
是一种相对宽松的设置。在大多数情况下,浏览器会在安全的跨站请求(如通过<a>
标签导航到目标网站)中发送Cookie,但在一些可能会导致CSRF攻击的情况下(如自动发送的GET请求)不会发送Cookie。 - None:设置为
None
时,浏览器会在所有跨站请求中发送Cookie,这是最不安全的设置,通常需要与Secure
属性一起使用,并且要求网站通过HTTPS访问。
- 可以通过设置Cookie的
- X - Frame - Options头
X - Frame - Options
是一个HTTP头,用于控制网站是否可以被其他网站通过<iframe>
等方式嵌入。设置这个头可以防止攻击者通过将目标网站嵌入到恶意页面中来进行CSRF攻击或者其他攻击(如点击劫持)。例如,设置X - Frame - Options: DENY
,表示禁止任何网站通过<iframe>
嵌入本网站。