點(diǎn)擊劫持中間件和裝飾器提供了簡(jiǎn)捷易用的,對(duì)點(diǎn)擊劫持的保護(hù)。這種攻擊在惡意站點(diǎn)誘導(dǎo)用戶點(diǎn)擊另一個(gè)站點(diǎn)的被覆蓋元素時(shí)出現(xiàn),另一個(gè)站點(diǎn)已經(jīng)加載到了隱藏的frame或iframe中。
假設(shè)一個(gè)在線商店擁有一個(gè)頁(yè)面,已登錄的用戶可以點(diǎn)擊“現(xiàn)在購(gòu)買”來(lái)購(gòu)買一個(gè)商品。用戶為了方便,可以選擇一直保持商店的登錄狀態(tài)。一個(gè)攻擊者的站點(diǎn)可能在他們自己的頁(yè)面上會(huì)創(chuàng)建一個(gè)“我喜歡Ponies”的按鈕,并且在一個(gè)透明的iframe中加載商店的頁(yè)面,把“現(xiàn)在購(gòu)買”的按鈕隱藏起來(lái)覆蓋在“我喜歡Ponies”上。如果用戶訪問(wèn)了攻擊者的站點(diǎn),點(diǎn)擊“我喜歡Ponies”按鈕會(huì)觸發(fā)對(duì)“現(xiàn)在購(gòu)買”按鈕的無(wú)意識(shí)的點(diǎn)擊,不知不覺(jué)中購(gòu)買了商品。
現(xiàn)代瀏覽器遵循X-Frame-Options協(xié)議頭,它表明一個(gè)資源是否允許加載到frame或者iframe中。如果響應(yīng)包含值為SAMEORIGIN的協(xié)議頭,瀏覽器會(huì)在frame中只加載同源請(qǐng)求的的資源。如果協(xié)議頭設(shè)置為DENY,瀏覽器會(huì)在加載frame時(shí)屏蔽所有資源,無(wú)論請(qǐng)求來(lái)自于哪個(gè)站點(diǎn)。
Django提供了一些簡(jiǎn)單的方法來(lái)在你站點(diǎn)的響應(yīng)中包含這個(gè)協(xié)議頭:
要為你站點(diǎn)中所有的響應(yīng)設(shè)置相同的X-Frame-Options值,將'django.middleware.clickjacking.XFrameOptionsMiddleware'設(shè)置為 MIDDLEWARE_CLASSES:
MIDDLEWARE_CLASSES = (
...
'django.middleware.clickjacking.XFrameOptionsMiddleware',
...
)
這個(gè)中間件可以在startproject生成的設(shè)置文件中開啟。
通常,這個(gè)中間件會(huì)為任何開放的HttpResponse設(shè)置X-Frame-Options協(xié)議頭為SAMEORIGIN。如果你想用 DENY來(lái)替代它,要設(shè)置X_FRAME_OPTIONS:
X_FRAME_OPTIONS = 'DENY'
使用這個(gè)中間件時(shí)可能會(huì)有一些視圖,你并不想為它設(shè)置X-Frame-Options協(xié)議頭。對(duì)于這些情況,你可以使用一個(gè)視圖裝飾器來(lái)告訴中間件不要設(shè)置協(xié)議頭:
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.")
Django提供了以下裝飾器來(lái)為每個(gè)基礎(chǔ)視圖設(shè)置X-Frame-Options協(xié)議頭。
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.")
注意你可以在中間件的連接中使用裝飾器。使用裝飾器來(lái)覆蓋中間件。
X-Frame-Options協(xié)議頭只在現(xiàn)代瀏覽器中保護(hù)點(diǎn)擊劫持。老式的瀏覽器會(huì)忽視這個(gè)協(xié)議頭,并且需要 其它點(diǎn)擊劫持防范技巧。
瀏覽器對(duì)X-Frame-Options支持情況的完整列表。
譯者:Django 文檔協(xié)作翻譯小組,原文:Clickjacking protection。
本文以 CC BY-NC-SA 3.0 協(xié)議發(fā)布,轉(zhuǎn)載請(qǐng)保留作者署名和文章出處。
Django 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質(zhì)。交流群:467338606。