Django笔记——CSRF

Django笔记

csrf

一、CSRF介绍

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种常见的Web安全漏洞,在这种攻击中,攻击者利用已登录用户的身份,在用户不知情的情况下向目标网站发送恶意请求,这些请求可以执行各种操作,例如更改密码、转账等,而这些操作本应是经过用户明确授权的。

  • 工作原理:假设用户登录了受信任的网站A,并在未登出的状态下访问了由攻击者控制的恶意网站B。如果网站B包含有特定构造的请求,指向网站A上的敏感操作,则由于浏览器会自动附带与网站A相关的认证信息(如cookies),导致网站A无法区分该请求是否确实来自用户的意图。
  • 防御措施
    • 使用CSRF Token:确保每个请求都携带一个随机生成的token,并且服务器端验证这个token的有效性。
    • 双重Cookie防御:通过设置特定的自定义HTTP头部来增加安全性。
    • 同源检查:基于HTTP请求的来源进行检查,确保请求是由合法页面发起的。
    • 验证码:虽然不是专门针对CSRF的防御手段,但验证码可以有效防止自动化工具发起的CSRF攻击。
二、Django中的CSRF保护
  • 默认启用的保护 :Django通过CsrfViewMiddleware中间件实现CSRF保护。它会对所有传入的POST、PUT等非安全HTTP方法的请求进行CSRF token验证。

  • 如何使用CSRF Token

    • 在HTML表单中添加{% csrf_token %}模板标签,以插入隐藏的输入字段,其值为当前用户的CSRF token。

      html 复制代码
      <form action="" method="POST">
              <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
      {#      {% csrf_token %}  或者直接使用{% csrf_token %}模板标签即可   #}
              <table>
                  <tbody>
                      <tr>
                          <td>邮箱:</td>
                          <td><input type="email" name="email"></td>
                      </tr>
                      <tr>
                          <td>密码:</td>
                          <td><input type="password" name="password"></td>
                      </tr>
                      <tr>
                          <td></td>
                          <td><input type="submit" value="登录"></td>
                      </tr>
                  </tbody>
              </table>

      {% csrf_token %}网页源代码显示如下:

    • 对于AJAX请求,需要手动将CSRF token添加到请求头中,可以通过JavaScript获取cookie中的CSRF token,并将其作为X-CSRFToken头部的一部分发送。

      js 复制代码
      $("#submit-btn").click(function (event) {
          // 阻止按钮的默认行为,默认是表单发送,要改成Ajax
          event.preventDefault();
          let title = $("input[name='title']").val();
          let category = $("#categoryInput").val();
          let content = editor.getHtml();
          let csrfmiddlewaretoken = $("input[name=csrfmiddlewaretoken]").val();
          $.ajax({
              url: "/blog/pub",
              method: "POST",
              data: { title, category, content, csrfmiddlewaretoken},
              success: function (result) {
                  if (result["code"] === 201){
                      // 获取帖子id
                      let blog_id = result["data"]["blog_id"];
                      // 跳转到帖子详情页面
                      window.location = '/blog/' + blog_id;
                  }
                  else
                  {
                      alert(result["message"]);
                  }
              }
      
          })
      })
  • 403错误:

    如果在Django中处理POST请求但没有在HTML表单中添加{% csrf_token %}模板标签,并且尝试通过AJAX或其他方式发送这个表单数据,Django的CSRF中间件会阻止这个请求并返回一个403 Forbidden错误。

相关推荐
丰锋ff21 分钟前
考研英一学习笔记
笔记·学习·考研
Invinciblenuonuo1 小时前
FreeRTOS学习笔记【10】-----任务上下文切换
笔记·学习
美味的大香蕉1 小时前
Spark-SQL与Hive
笔记
_Hello_Panda_1 小时前
FX10(CYUSB4014)USB3.2(10Gbps)开发笔记分享(1):硬件设计与开发环境搭建
笔记·fpga开发·fx10·cyusb4014
时间之城2 小时前
笔记:记一次使用EasyExcel重写convertToExcelData方法无法读取@ExcelDictFormat注解的问题(已解决)
java·spring boot·笔记·spring·excel
灏瀚星空2 小时前
用Obsidian四个插件打造小说故事关联管理系统:从模板到图谱的全流程实践
经验分享·笔记·开源
一只可爱的小猴子3 小时前
2022李宏毅老师机器学习课程笔记
人工智能·笔记·机器学习
孞㐑¥3 小时前
C++11介绍
开发语言·c++·经验分享·笔记
小杰love编程3 小时前
Django 入门指南:构建强大的 Web 应用程序
前端·django·sqlite
使一颗心免于哀伤3 小时前
《重构》笔记摘录 - 9.处理继承关系
笔记