点击劫持保护¶
点击劫持中间件和装饰器提供易于使用的保护,以防止 点击劫持 。 当恶意网站欺骗用户点击另一个网站的隐藏元素时,就会发生这种类型的攻击,该元素已被加载到一个隐藏的框架或 iframe 中。
点击劫持的一个例子¶
Suppose an online store has a page where a logged-in user can click "Buy Now" to purchase an item. A user has chosen to stay logged into the store all the time for convenience. An attacker site might create an "I Like Ponies" button on one of their own pages, and load the store's page in a transparent iframe such that the "Buy Now" button is invisibly overlaid on the "I Like Ponies" button. If the user visits the attacker's site, clicking "I Like Ponies" will cause an inadvertent click on the "Buy Now" button and an unknowing purchase of the item.
防止点击劫持¶
现代浏览器尊重 X-Frame-Options HTTP 头,它表明是否允许在框架或 iframe 中加载资源。如果响应包含值为 SAMEORIGIN
的头,那么只有当请求来自同一个网站时,浏览器才会在框架中加载资源。如果头被设置为 DENY
,那么无论请求是由哪个网站发出的,浏览器都会阻止资源在框架中加载。
Django 提供了一些方法来在你的网站的响应中包含这个头:
一个在所有响应中设置头的中间件。
一组可用于覆盖中间件或仅为某些视图设置头的视图装饰器。
X-Frame-Options
HTTP 头只有在响应中还没有出现的情况下,才会被中间件或视图装饰者设置。
如何使用它¶
为所有响应设置 X-Frame-Options
¶
要为你的网站的所有响应设置相同的 X-FrameOptions
值,把 'django.middleware.clickjacking.XFrameOptionsMiddleware'
放到 MIDDLEWARE
:
MIDDLEWARE = [
...,
"django.middleware.clickjacking.XFrameOptionsMiddleware",
...,
]
这个中间件在 startproject
生成的配置文件中启用了。
默认情况下,中间件将为每个传出的 HttpResponse
设置 X- 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.")
Note
如果你想在框架或 iframe 中提交表单或访问会话 cookie,你可能需要修改 CSRF_COOKIE_SAMESITE
或 SESSION_COOKIE_SAMESITE
配置。
为每个视图设置 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.")
请注意,你可以将装饰器与中间件一起使用。使用装饰器可以覆盖中间件。
限制¶
X-Frame-Options
头部仅能在 现代浏览器 中防止点击劫持。