Django中如何防范CSRF跨站点请求伪造攻击的实现

木白
木白
发布时间:2026-10-13| 4人浏览过
原创

本文详细解析Django框架中防范CSRF(跨站点请求伪造)攻击的机制。通过介绍CsrfMiddleware的工作原理,包括Token生成与验证流程,以及具体的配置步骤,如设置中间件顺序、在模板中添加csrf_token标签及使用RequestContext,帮助开发者构建安全的Web应用,防止恶意用户利用已登录身份执行非法操作。

CSRF概念与攻击原理

CSRF概念

CSRF全称为Cross-Site Request Forgery,即跨站点请求伪造。

这种攻击中,攻击者窃取用户的身份凭证,以用户的名义向服务器发送恶意请求。对服务器而言,这些请求看似合法,但实际上执行了攻击者预期的操作,例如发送电子邮件、发布消息、窃取账号权限、添加系统管理员,甚至进行商品购买或虚拟货币转账等。

CSRF攻击原理以及过程

首先,用户C打开浏览器,访问受信任的网站A,输入用户名和密码请求登录;

用户信息通过验证后,网站A生成Cookie信息并返回给浏览器,此时用户登录成功,可以正常向网站A发送请求;

在用户未退出网站A的情况下,在同一浏览器中打开一个新的TAB页访问网站B;

网站B接收到用户请求后,返回包含攻击性代码的内容,并发出一个指向第三方站点A的请求;

浏览器接收到这些攻击性代码后,在用户不知情的情况下,携带Cookie信息向网站A发出请求。由于网站A无法区分该请求是由B发起的还是用户主动发起的,因此会根据用户C的Cookie信息处理该请求,导致来自网站B的恶意代码被执行。

CSRF攻击实例分析

CSRF攻击实例

假设受害者Bob在银行网站有一笔存款,通过向银行网站发送请求 http://bank.example/withdraw?account=bob&amount=1000000&for=bob2,可以将Bob的1000000存款转到bob2的账号下。通常情况下,银行网站会验证该请求是否来自合法的session,并确认用户Bob已登录。

黑客Mallory也在该银行拥有账户,他知道上述URL可以执行转账操作。Mallory可以自行向银行发送请求:http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory。但由于该请求来自Mallory而非Bob,无法通过安全认证,因此请求无效。

此时,Mallory采用CSRF攻击方式,他创建了一个包含如下代码的网站:src=”http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory ”,并通过广告等手段诱使Bob访问。当Bob访问该网站时,上述URL会从Bob的浏览器发向银行,并附带Bob浏览器中的Cookie信息。大多数情况下,由于需要Bob的认证信息,请求会失败。但如果Bob刚访问过银行网站,Session尚未过期,浏览器Cookie中包含Bob的认证信息,则请求会成功响应,资金将从Bob账户转移到Mallory账户。Bob事后查询日志时,只能看到来自本人的合法请求,无法察觉被攻击,而Mallory则可顺利获取资金。

Django CSRF防护机制

Django中如何防范CSRF

Django使用专门的中间件(CsrfMiddleware)来进行CSRF防护。具体的原理如下:

1. 该中间件会修改当前处理的请求,向所有POST表单中添加一个隐藏的表单字段,名称为csrfmiddlewaretoken,值为当前会话ID加上一个密钥的散列值。如果未设置会话ID,该中间件不会修改响应结果,因此对于未使用会话的请求,性能损失可忽略不计。

2. 对于所有包含会话Cookie集合的传入POST请求,中间件将检查是否存在csrfmiddlewaretoken及其是否正确。如果不符合要求,用户将收到403 HTTP错误,错误页面内容提示检测到跨域请求伪装,并终止请求。

此步骤确保只有源自本站点的表单才能将数据POST回来。

此外,未使用会话Cookie的POST请求无法受到保护,但也不需要保护,因为恶意网站可用任意方法制造此类请求。为避免修改非HTML请求,中间件在编辑响应结果前会检查Content-Type头标。只有标记为text/html或application/xml+xhtml的页面才会被修改。

Django防范CSRF的具体操作

1. 将'django.middleware.csrf.CsrfViewMiddleware'添加到Django的settings.py文件中的MIDDLEWARE_CLASSES列表中(默认已添加)。该中间件必须在SessionMiddleware之后执行,因此在列表中CsrfMiddleware必须出现在SessionMiddleware之前(因为响应中间件是自后向前执行的)。同时,它也必须在响应被压缩或解压之前对响应结果进行处理,因此CsrfMiddleware必须在GZipMiddleware之后执行。

Django具体配置与代码实现


MIDDLEWARE_CLASSES = (
  'django.middleware.common.CommonMiddleware',
  'django.contrib.sessions.middleware.SessionMiddleware',
  'django.middleware.csrf.CsrfViewMiddleware',
  'django.contrib.auth.middleware.AuthenticationMiddleware',
  'django.contrib.messages.middleware.MessageMiddleware',
  # Uncomment the next line for simple clickjacking protection:
  # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

2. 在使用POST方法提交FORM的页面中,添加csrf_token标签,例如:


<form action="." method="post">{% csrf_token %}

3. 在相应的view中,确保“django.core.context_processors.csrf”上下文处理器被正确使用,有两种方法实现这一点:一是使用RequestContext,它内部会自动使用“django.core.context_processors.csrf”;另一种方法是手动使用这个处理器,示例代码如下:


from django.core.context_processors import csrf
from django.shortcuts import render_to_response
def my_view(request):
  c = {}
  c.update(csrf(request))
  # ... view code here
return render_to_response("a_template.html", c)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。