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

相关推荐
Hello_Embed1 天前
STM32HAL 快速入门(二十):UART 中断改进 —— 环形缓冲区解决数据丢失
笔记·stm32·单片机·学习·嵌入式软件
咸甜适中1 天前
rust语言 (1.88) 学习笔记:客户端和服务器端同在一个项目中
笔记·学习·rust
Grassto1 天前
RAG 从入门到放弃?丐版 demo 实战笔记(go+python)
笔记
Magnetic_h1 天前
【iOS】设计模式复习
笔记·学习·ios·设计模式·objective-c·cocoa
计算机编程小央姐1 天前
跟上大数据时代步伐:食物营养数据可视化分析系统技术前沿解析
大数据·hadoop·信息可视化·spark·django·课程设计·食物
诗句藏于尽头1 天前
Django模型与数据库表映射的两种方式
数据库·python·django
周周记笔记1 天前
学习笔记:第一个Python程序
笔记·学习
丑小鸭是白天鹅1 天前
Kotlin协程详细笔记之切线程和挂起函数
开发语言·笔记·kotlin
潘达斯奈基~1 天前
《大数据之路1》笔记2:数据模型
大数据·笔记
..过云雨1 天前
05.【Linux系统编程】进程(冯诺依曼体系结构、进程概念、进程状态(注意僵尸和孤儿)、进程优先级、进程切换和调度)
linux·笔记·学习