当前位置: 首页 > news >正文

跨站请求伪造:揭秘攻击与防御

1、什么是CSRF

其目标是在用户不知情的情况下,以用户身份执行未经授权的操作。攻击者通过引诱用户访问恶意网站或点击包含恶意代码的链接,来伪造一个请求发送给服务器,来触发 CSRF 攻击。一旦用户被攻击,他们的登录凭据将被用于执行可能涉及敏感操作的请求,例如更改密码、发表评论、转账等。

2、原理

前提:用户登录网站后,浏览器会记录网站的cookie,当用户再次请求网站的时候,浏览器会把网站下的cookie带上发给服务器。
1、假如用户使用浏览器登录了淘宝网,并且浏览器已经保存了淘宝网的cookie
2、用户又打开一个标签登录了邮箱,打开邮件里的链接,该链接就是伪造的攻击链接
3、用户点击后会访问淘宝店铺的好评链接,此时浏览器已经有了用户的淘宝网的cookie,这次请求服务器就会认为是用户正常发送的,就会执行好评请求,这样就造成CSRF。

3、防护

1、检查Referer和Origin字段

HTTP请求头会默认带上Referer字段和Origin字段,Referer这个字段用以标明请求来源于哪个地址。Origin它表示请求的来源,即请求来自于哪个站点,Origin只包含服务器名。一般情况下,Origin和Referer字段应和请求的地址位于同一域名下。如果不是同一域名下,服务器就会识别为恶意访问。

2、使用CSRF令牌(CSRF Token)

在每个用户会话中生成一个随机的CSRF令牌,并将其嵌入到每个表单或敏感操作的请求中。这个令牌是服务器生成的,并与用户的会话相关联。服务器在接收到请求时会验证这个令牌的有效性,确保请求来自合法的源。攻击者无法获得有效的CSRF令牌,因此无法成功发起CSRF攻击。

3、Cookie的SameSite属性

在设置Cookie时,可以将SameSite属性设置为"Strict"或"Lax",以限制跨站请求的Cookie传递。这有助于减少CSRF攻击的成功率,Strict完全禁止,Lax相对宽松,None不做限制

4、django中的防护

1、首先在settings.py中启用CSRF保护

MIDDLEWARE = [# ...'django.middleware.csrf.CsrfViewMiddleware', # 开启CSRF中间件# ...
]

2、在所有包含表单的HTML模板中,确保包含{% csrf_token %}标签,会隐藏一个CSRF令牌

<form method="post" action="/example/">{% csrf_token %}<!-- 其他表单字段 --><input type="submit" value="提交">
</form><!--会变成下面-->
<form method="post" action="/example/"><input type="hidden" name="csrfmiddlewaretoken" value="cxIrGQrJOzVN3NcleAjFEbYZfSE8LbIJuuPW6Vx7H3IliRg26FCQHgzMjwWWQp9u"><!-- 其他表单字段 --><input type="submit" value="提交">
</form>

3、用户第一层访问网站时,django会随机生成一个csrftoken,放在浏览器的cookie中,后面每次请求的时候都会带上这个csrftoken
4、当用户提交表单的时候,CsrfViewMiddleware中间件会自动校验cookie和表单中的csrftoken是否一致,来判定是否是合法请求。
5、每次刷新表单的时候,csrfmiddlewaretoken会更新,而cookie中的csrftoken没变,如何校验呢?csrftoken只比较secret,token前32位是salt,后面是加密的token,通过salt能解密出唯一的secret,其实最终比较的是secret。

# CsrfViewMiddleware/process_view中
csrf_token = self._get_token(request) # 从cookie中获取csrftoken
request_csrf_token = request.POST.get('csrfmiddlewaretoken', '') # 从表单中获取csrfmiddlewaretoken_compare_masked_tokens(request_csrf_token, csrf_token) # 比较def _compare_masked_tokens(request_csrf_token, csrf_token):# Assume both arguments are sanitized -- that is, strings of# length CSRF_TOKEN_LENGTH, all CSRF_ALLOWED_CHARS.return constant_time_compare(_unmask_cipher_token(request_csrf_token),_unmask_cipher_token(csrf_token),)def _unmask_cipher_token(token):"""Given a token (assumed to be a string of CSRF_ALLOWED_CHARS, of lengthCSRF_TOKEN_LENGTH, and that its first half is a mask), use it to decryptthe second half to produce the original secret."""mask = token[:CSRF_SECRET_LENGTH]token = token[CSRF_SECRET_LENGTH:]chars = CSRF_ALLOWED_CHARSpairs = zip((chars.index(x) for x in token), (chars.index(x) for x in mask))return ''.join(chars[x - y] for x, y in pairs)  # Note negative values are ok

6、django后端实现,@csrf_exempt 装饰器用于关闭 CSRF 保护,即使在全局中间件中已经启用了 CSRF 保护。@csrf_protect 装饰器用于强制启用 CSRF 保护,即使在全局中间件中已经启用了 CSRF 保护。

from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt, csrf_protect@csrf_exempt
def index(request):return render(request, 'index.html', locals())@csrf_protect
def pay(request):pass
http://www.lryc.cn/news/192933.html

相关文章:

  • matlab 图像均值滤波
  • P1433 吃奶酪
  • c++string类的赋值问题
  • 服务器中了mkp勒索病毒怎么办?mkp勒索病毒特点,解密数据恢复
  • 深入探析网络代理与网络安全
  • 如何开始使用 Kubernetes RBAC
  • 8.简易无线通信
  • 渗透测试漏洞挖掘技巧
  • Nginx - 反向代理与负载均衡
  • Linux网络编程系列之UDP组播
  • 设计模式~状态模式(state)-23
  • linux环境下使用lighthouse与selenium
  • NeuroImage | 右侧颞上回在语义规则学习中的作用:来自强化学习模型的证据
  • uni-app编程checkbox-group获取选中的每个checkbox的value值
  • 数组——螺旋矩阵II
  • 反范式化设计
  • CCF CSP认证 历年题目自练Day31
  • PCL点云处理之从两片点云中获取具有匹配关系的同名点对 (二百一十八)
  • MySQL Row size too large (> 8126)
  • HUAWEI(26)——防火墙双机热备
  • 【ArcGIS】NDVI估算植被覆盖度FVC
  • vscode用密钥文件连接ssh:如果一直要输密码怎么办
  • 【AI视野·今日Robot 机器人论文速览 第五十三期】Thu, 12 Oct 2023
  • 【LeetCode第115场双周赛】100029. 和带限制的子多重集合的数目 | 前缀和背包 | 中等
  • ArcGIS笔记5_生成栅格文件时保存报错怎么办
  • YOLO目标检测——跌倒摔倒数据集【含对应voc、coco和yolo三种格式标签】
  • uniapp小程序实现绘制内容,生成海报并保存截图(Painter和Canvas两种方式举例)
  • HTTPS双向认证及密钥总结
  • Mybatis用Byte[]存图片,前端显示图片
  • MacBook/MacOS如何更新到指定的版本