点击劫持防护

点击劫持中间件和装饰器提供了易于使用的针对点击劫持的保护。这种类型的攻击发生在恶意网站诱骗用户点击另一个网站的隐藏元素时,这些元素已加载到隐藏的框架或 iframe 中。

点击劫持示例

假设一家在线商店有一个页面,登录用户可以在其中点击“立即购买”来购买商品。为方便起见,用户选择一直登录到商店。攻击者网站可能会在其自身页面上创建一个“我喜欢小马”按钮,并在透明的 iframe 中加载商店的页面,以便“立即购买”按钮隐形地叠加在“我喜欢小马”按钮上。如果用户访问攻击者的网站,点击“我喜欢小马”将导致无意中点击“立即购买”按钮,并不知情地购买商品。

防止点击劫持

现代浏览器遵循X-Frame-Options HTTP 头,该头指示资源是否允许在框架或 iframe 中加载。如果响应包含值为SAMEORIGIN的头,则浏览器只有在请求源于同一站点时才会在框架中加载资源。如果将标头设置为DENY,则浏览器将阻止资源在框架中加载,无论哪个站点发出了请求。

Django 提供了几种方法可以在您站点的响应中包含此标头

  1. 一个在所有响应中设置标头的中间件。

  2. 一组视图装饰器,可用于覆盖中间件或仅为某些视图设置标头。

只有在响应中不存在X-Frame-Options HTTP 标头时,中间件或视图装饰器才会设置它。

使用方法

为所有响应设置X-Frame-Options

要在您网站的所有响应中设置相同的X-Frame-Options值,请将'django.middleware.clickjacking.XFrameOptionsMiddleware'添加到MIDDLEWARE

MIDDLEWARE = [
    ...,
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    ...,
]

此中间件在startproject生成的设置文件中启用。

默认情况下,中间件会为每个传出的HttpResponseX-Frame-Options标头设置为DENY。如果您希望使用其他值,请设置X_FRAME_OPTIONS设置

X_FRAME_OPTIONS = "SAMEORIGIN"

使用中间件时,可能某些视图不需要设置X-Frame-Options标头。对于这些情况,您可以使用一个视图装饰器来告诉中间件不要设置标头。

from django.http import HttpResponse
from django.views.decorators.clickjacking import xframe_options_exempt


@xframe_options_exempt
def ok_to_load_in_a_frame(request):
    return HttpResponse("This page is safe to load in a frame on any site.")

注意

如果您想在框架或 iframe 内提交表单或访问会话 Cookie,您可能需要修改CSRF_COOKIE_SAMESITESESSION_COOKIE_SAMESITE设置。

Django 5.0 中的更改

@xframe_options_exempt装饰器添加了包装异步视图函数的支持。

按视图设置X-Frame-Options

要按视图设置X-Frame-Options标头,Django 提供了这些装饰器:

from django.http import HttpResponse
from django.views.decorators.clickjacking import xframe_options_deny
from django.views.decorators.clickjacking import xframe_options_sameorigin


@xframe_options_deny
def view_one(request):
    return HttpResponse("I won't display in any frame!")


@xframe_options_sameorigin
def view_two(request):
    return HttpResponse("Display in a frame if it's from the same origin as me.")

请注意,您可以将装饰器与中间件结合使用。装饰器的使用会覆盖中间件。

Django 5.0 中的更改

@xframe_options_deny@xframe_options_sameorigin装饰器添加了包装异步视图函数的支持。

限制

X-Frame-Options标头仅会在现代浏览器中防止点击劫持。

返回顶部