哈囉,我們又見面了,到了這系列的尾聲,就讓我們用 網路安全 議題來結束這系列吧 !
本篇內容主要是參考 Security in Django 官方文件作為文章大綱,再結合大神們對於各項攻擊防禦的文章,所產出的一篇綜觀 Django
的安全議題文章。
XSS
(Cross-site scripting)詳細可以參考 【網頁安全】給網頁開發新人的 XSS 攻擊 介紹與防範 | 巴哈程設版,這篇解釋得蠻簡單易懂的。
XSS
是什麼 ?簡單來說,就是攻擊者透過一些方式,能夠在你的網站上,執行攻擊者自己寫的程式碼,這件事可輕可重,輕可變成整人的彈跳視窗,重可變成我也不知道 XD
XSS
範例在 HTML
頁面中,想要輸出一行帶有使用者名字的字串
Hello, {{ name }}
如果使用者名字是一般的名字的話,那沒什麼問題
但如果有人的名字長 "<script>alert("You've been hacked")</script>"
的話,沒有經過檢查就 render 出來就會變成
Hello, <script>alert("You've been hacked")</script>
使用者端就會跳出一個 You've been hacked
的視窗。
Django
對 XSS
的解決方法Django 的 Templates
有提供防護 XSS 的方法
Django 事先想到了這一點,所以 Django 提出了一個 automatic HTML escaping
,像是 <
會被轉成 <
,而 >
會被轉成 >
,'
會被轉成 '
,"
會被轉成 "
,&
會被轉成 &
。
這些轉換都是 Django 預設的,也就是說,就算你不知道 Django 有 automatic HTML escaping
的機制,你還是會受到保護,防止惡意的 injection。
如果你在某些欄位要關掉這一層的防護機制,只要加上 |safe
就可以關掉 escaping。
This can disable HTML escaping: {{ data|safe }}
但,這只是最基本的保護機制,還是會有漏洞,漏洞的舉例可以參考官方文件,只不過 Django 的 automatic HTML escaping
機制,已經能防止很大部分的 XSS 攻擊了,剩下的防禦就看開發者的實力如何了。
CSRF
(Cross-site request forgery)Django 也有防禦 CSRF
的機制,光是一個 CSRF
的防禦機制,在官方文件就已經是一大篇了XD,對於想更深入瞭解 Django 安全機制的人們,就很值得好好 K 這篇文件。
CSRF
攻擊?詳細可以參考 讓我們來談談 CSRF | TechBridge 技術共筆部落格,這篇講的是真的很詳細,文章寫得也很不錯,很漸進式的帶入 CSRF
攻擊的影響程度。
簡單來說,CSRF
就是由攻擊者 "代替" 不知情的使用者,執行了一次按鈕,影響程度就要看這個按鈕是什麼按鈕了,如果這個按鈕是對網頁連結到下一頁,那沒什麼問題,那如果是轉帳的按鈕呢 ? 不過目前大部分大型的金融機構,對於轉帳都有基本的防護機制,不用怕 CSRF
就不使用網站轉帳了 XD
這種攻擊方式是利用了瀏覽器順帶 Cookie
的機制,進而仿造使用者曾經做過的行為。
借用一下 讓我們來談談 CSRF | TechBridge 技術共筆部落格 的一個範例
今天假設小黑是一個邪惡的壞蛋,想要讓小明在不知情的情況下就把自己的文章刪掉,該怎麼做呢?
他知道小明很喜歡心理測驗,於是就做了一個心理測驗網站,並且發給小明。
但這個心理測驗網站跟其他網站不同的點在於,「開始測驗」的按鈕長得像這樣:
開始測驗
小明收到網頁之後很開心,就點擊「開始測驗」。點擊之後瀏覽器就會發送一個 GET 請求給https://small-min.blog.com/delete?id=3 ,並且因為瀏覽器的運行機制,一併把 small-min.blog.com 的 cookie 都一起帶上去。
Server 端收到之後檢查了一下 session,發現是小明,而且這篇文章也真的是小明發的,於是就把這篇文章給刪除了。
這就是 CSRF,你現在明明在心理測驗網站,假設是 https://test.com 好了,但是卻在不知情的狀況下刪除了 https://small-min.blog.com 的文章,你說這可不可怕?超可怕!
詳細可以參考官方文件,簡單來說,Django 會透過 CsrfViewMiddleware
,來檢查每個 POST request 裡面的 csrfmiddlewaretoken
(這個 token 不是只是一個值這麼簡單),還有檢查 referrer
欄位是不是同一個 domain。
SQL injection
SQL injection
?詳細可以參考 一次看懂 SQL Injection 的攻擊原理 | Medium,這篇舉了很多有趣的例子,不會一開始就丟語法進來跟你解釋。
概念很像是 XSS,都是看準伺服器端偷懶,沒有檢查接收進來的內容,簡單來說,攻擊者透過輸入一串值,而伺服器端收到這串值之後,放到 SQL 語法中,卻會是一個合法的 SQL 語法,這就是 SQL injection,我知道聽起來有點繞口,所以需要一個範例。
再次借用 一次看懂 SQL Injection 的攻擊原理 | Medium 這篇的範例,假設現在要透過 SQL 語法進行使用者帳號密碼的判斷,如果使用者的名稱 和 密碼 都正確,才可以讀取使用者資料,但攻擊者在只知道使用者帳號、不知道密碼的情況之下,可能可以透過 SQL injection,"繞過" 密碼的判斷。
正常情況下的使用者帳號密碼判斷,需要帳號和密碼都正確才行
而,攻擊者可以把密碼的欄位,改成 abc' or '1'='1
(這邊注意一下單引號的位置),也就是下圖中黃色的密碼欄位所呈現的
如果伺服器端沒有對欄位進行檢查,直接把欄位帶入到 SQL 語法去執行的話,就會成為另一段合法的 SQL 語法,可是卻不是伺服器端所設計的邏輯,藉由這樣的方法,攻擊者就達成了目的。
SQL injection
?Django 採用 MVT
Pattern (Model-View-Template),開發者只要寫 Model 部分,而 Model 到 DB 之間會透過 database driver
來轉換,所以 Django 開發者通常不需要寫 Raw SQL 語法,自然就比較難發生 SQL injection 的攻擊。
Clickjacking
Django 的官方文件有提到 Clickjacking
的防禦機制,Clickjacking
就是 Click
+ Hijacking
(劫持/劫機),你可以把它想成,按鈕是飛機的機長,而攻擊者利用 Clickjacking
的技術,強迫機長改飛另一個方向( 強迫按鈕改作另一件事情 )的感覺。
Clickjacking
?詳細可以參考 淺談IFrame式Clickjacking攻擊與防護 | 黑暗執行緒,這篇一開頭就有個範例: 在我們自己的網頁中內嵌一個 google 搜尋首頁,利用的是 HTML
的 frame
標籤,而在實作上,可以在我們的網頁內嵌一個 Youtube 頁面,這樣就不用自己實作播放器了,這麼做是省事,可是卻容易造成漏洞。
簡單來說,ClickJacking
就是 你以為的按鈕 不是 你以為的按鈕,你以為你點了一個下一頁的按鈕,可是它可能是一個打開筆電前鏡頭的按鈕,也可能是一個載入木馬程式的按鈕,利用的是把 frame 設為透明的,變成在頁面顯示你以為的網頁,但背後卻隱藏真實的網頁。現在的瀏覽器會有 x-frame-options
的防禦機制,來保護使用者意外執行惡意的 frame。
Clickjacking
?Django 透過 X-Frame-Options middleware
,把 X-Frame-Options
的 header 改成 DENY,也就是不給嵌入 frame,直接杜絕 Clickjacking 的機會。
如果在某個頁面想要允許 X-Frame
的話,那就使用 @xframe_options_exempt
的 decorator
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.")
經過這一系列的文章,我深深感覺到了有框架的幫忙,真的對開發後端非常有幫助,框架幫開發者做的事情太多了,即使是開發新手,不要手賤把一些保護機制取消掉的話,都能受到基本的保護。要瞭解一個框架,需要花一段時間的相處、深讀文件,才能知道一個框架的設計精神。
覺得最近我的心已經開始飄飄的,沒辦法好好靜下來寫文章,很急著想要趕快進行到下一個階段,恨不得趕快把這系列終結 XD,在寫最後這幾篇的時候,就會感覺特別難寫,寫到一半的時候,想到其他有趣的東西,就很想要趕快去 survey,但時間又沒那麼多,只好把這樣的慾望給壓下來,好難受 QQ,希望趕快度過這幾天!!
我是 RS,這是我的 不做怎麼知道系列 文章,我們 明天見。
Django 事先想到了這一點,所以 Django 提出了一個 automatic HTML escaping,像是 < 會被轉成 <,而 > 會被轉成 >,' 會被轉成 '," 會被轉成 ",& 會被轉成 &。
不好意思想問一下xDD
這個轉換是型態轉換還是什麼方式?
轉換有點看不懂他轉了什麼看起來都一樣Orz (是不是我便便吃不夠
啊~~~~
我竟然沒注意到,被編輯器轉碼了QQ
感謝你看得這麼仔細哈哈
應該是要這樣:
Django 事先想到了這一點,所以 Django 提出了一個 automatic HTML escaping,像是
<
會被轉成<
,而>
會被轉成>
,'
會被轉成'
,"
會被轉成"
,&
會被轉成&
。
了解了解~
感謝xDD