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错误。

相关推荐
霸王蟹几秒前
React Hooks 必须在组件最顶层调用的原因解析
前端·javascript·笔记·学习·react.js
珊瑚里的鱼4 分钟前
【滑动窗口】LeetCode 1658题解 | 将 x 减到 0 的最小操作数
开发语言·c++·笔记·算法·leetcode·stl
请你喝好果汁6412 小时前
Jupyter Notebook 配置学习笔记
笔记·学习·jupyter
Lester_11015 小时前
嵌入式学习笔记 - STM32 ADC 模块工作模式总结
笔记·学习
愚戏师11 小时前
Linux复习笔记(六)shell编程
linux·笔记·shell
.(ᗜ ˰ ᗜ) .12 小时前
机器学习笔记2
笔记
noravinsc12 小时前
redis是内存级缓存吗
后端·python·django
小葡萄202513 小时前
黑马程序员c++2024版笔记 第一章 变量和基本类型
笔记·c++20
百锦再13 小时前
大数据技术的主要方向及其应用详解
大数据·linux·网络·python·django·pygame
顾子茵13 小时前
计算机图形学基础--Games101笔记(一)数学基础与光栅化
笔记·图形渲染