Django Web 應用程式安全性

保護使用者資料是任何網站設計的重要組成部分。我們之前在文章Web 安全中解釋了一些更常見的安全威脅——本文實際演示了 Django 內建保護如何處理這些威脅。

預備知識 閱讀伺服器端程式設計“網站安全”主題。完成 Django 教程主題,至少包括Django 教程第 9 部分:使用表單
目標 瞭解您需要做(或不需做)的主要事情,以保護您的 Django Web 應用程式。

概述

網站安全主題概述了伺服器端設計中網站安全的含義,以及您應該防範的一些更常見威脅。該文章中的一個關鍵資訊是,當 Web 應用程式信任來自瀏覽器的資料時,幾乎所有攻擊都會成功。

警告:您能學到的關於網站安全最重要的一課是永遠不要信任來自瀏覽器的資料。這包括 URL 引數中的GET請求資料、POST資料、HTTP 標頭和 Cookie、使用者上傳的檔案等。始終檢查並清理所有傳入資料。始終假設最壞的情況。

對 Django 使用者來說,好訊息是許多更常見的威脅都由框架處理了!Django 中的安全(Django 文件)文章解釋了 Django 的安全功能以及如何保護由 Django 支援的網站。

常見威脅/保護

本文不會重複 Django 文件,而是將在我們的 Django LocalLibrary 教程中演示一些安全功能。

跨站指令碼 (XSS)

XSS 是一個術語,用於描述一類攻擊,允許攻擊者透過網站將客戶端指令碼注入其他使用者的瀏覽器。這通常透過將惡意指令碼儲存在資料庫中,然後檢索並顯示給其他使用者來實現,或者透過讓使用者點選一個連結,導致攻擊者的 JavaScript 在使用者瀏覽器中執行。

Django 的模板系統透過轉義 HTML 中“危險”的特定字元來保護您免受大多數 XSS 攻擊。我們可以透過嘗試使用我們在Django 教程第 9 部分:使用表單中設定的建立作者表單向我們的 LocalLibrary 網站注入一些 JavaScript 來演示這一點。

  1. 使用開發伺服器啟動網站(python3 manage.py runserver)。

  2. 在本地瀏覽器中開啟網站並登入您的超級使用者帳戶。

  3. 導航到作者建立頁面(其 URL 應該是:http://127.0.0.1:8000/catalog/author/create/)。

  4. 為新使用者輸入姓名和日期詳細資訊,然後將以下文字附加到姓氏欄位:<script>alert('Test alert');</script>作者表單 XSS 測試

    注意:這是一個無害的指令碼,如果執行,將在您的瀏覽器中顯示一個警報框。如果在提交記錄時顯示警報,則該站點容易受到 XSS 威脅。

  5. 提交儲存記錄。

  6. 儲存作者後,它將顯示如下。由於 XSS 保護,alert()不應執行。相反,指令碼以純文字顯示。作者詳細檢視 XSS 測試

如果您檢視頁面 HTML 原始碼,您會看到指令碼標籤的危險字元已轉換為無害的轉義碼等效項(例如,>現在是&gt;

html
<h1>
  Author: Boon&lt;script&gt;alert(&#39;Test alert&#39;);&lt;/script&gt;, David
  (Boonie)
</h1>

使用 Django 模板可以保護您免受大多數 XSS 攻擊。但是,可以關閉此保護,並且保護不會自動應用於通常不會由使用者輸入填充的所有標籤(例如,表單欄位中的help_text通常不是使用者提供的,因此 Django 不會轉義這些值)。

XSS 攻擊也可能源自其他不受信任的資料來源,例如 Cookie、Web 服務或上傳檔案(只要資料在包含到頁面中之前沒有經過充分清理)。如果您要顯示來自這些來源的資料,則可能需要新增自己的清理程式碼。

跨站請求偽造 (CSRF) 保護

CSRF 攻擊允許惡意使用者在其他使用者不知情或未經同意的情況下,使用其憑據執行操作。例如,考慮一個駭客想要為我們的 LocalLibrary 建立更多作者的情況。

注意:顯然我們的駭客不是為了錢!一個更有野心的駭客可以在其他網站上使用相同的方法執行更具破壞性的任務(例如,將錢轉入他們自己的賬戶,等等)。

為了做到這一點,他們可能會建立一個像下面這樣的 HTML 檔案,其中包含一個作者建立表單(就像我們在上一節中使用的那個),該表單在檔案載入後立即提交。然後他們會將檔案傳送給所有圖書管理員,並建議他們開啟檔案(它包含一些無害的資訊,真的!)。如果任何已登入的圖書管理員打開了該檔案,則該表單將以他們的憑據提交,並會建立一個新的作者。

html
<html lang="en">
  <body onload="document.EvilForm.submit()">
    <form
      action="http://127.0.0.1:8000/catalog/author/create/"
      method="post"
      name="EvilForm">
      <table>
        <tr>
          <th><label for="id_first_name">First name:</label></th>
          <td>
            <input
              id="id_first_name"
              maxlength="100"
              name="first_name"
              type="text"
              value="Mad"
              required />
          </td>
        </tr>
        <tr>
          <th><label for="id_last_name">Last name:</label></th>
          <td>
            <input
              id="id_last_name"
              maxlength="100"
              name="last_name"
              type="text"
              value="Man"
              required />
          </td>
        </tr>
        <tr>
          <th><label for="id_date_of_birth">Date of birth:</label></th>
          <td>
            <input id="id_date_of_birth" name="date_of_birth" type="text" />
          </td>
        </tr>
        <tr>
          <th><label for="id_date_of_death">Died:</label></th>
          <td>
            <input
              id="id_date_of_death"
              name="date_of_death"
              type="text"
              value="12/10/2016" />
          </td>
        </tr>
      </table>
      <input type="submit" value="Submit" />
    </form>
  </body>
</html>

執行開發 Web 伺服器,並使用您的超級使用者帳戶登入。將上面的文字複製到一個檔案中,然後在瀏覽器中開啟它。您應該會收到一個 CSRF 錯誤,因為 Django 對此類事情有保護!

啟用保護的方法是,您在表單定義中包含{% csrf_token %}模板標籤。然後,此令牌將像下面所示那樣在您的 HTML 中呈現,其值對於當前瀏覽器上的使用者是特定的。

html
<input
  type="hidden"
  name="csrfmiddlewaretoken"
  value="0QRWHnYVg776y2l66mcvZqp8alrv4lb8S8lZ4ZJUWGZFA5VHrVfL2mpH29YZ39PW" />

Django 生成一個使用者/瀏覽器特定的金鑰,並將拒絕不包含該欄位或包含使用者/瀏覽器不正確欄位值的表單。

要使用這種型別的攻擊,駭客現在必須發現幷包含特定目標使用者的 CSRF 金鑰。他們也不能使用“撒網”方法向所有圖書管理員傳送惡意檔案,並希望其中一個會開啟它,因為 CSRF 金鑰是瀏覽器特定的。

Django 的 CSRF 保護預設開啟。您應該始終在表單中使用{% csrf_token %}模板標籤,並對可能更改或新增資料到資料庫的請求使用POST

其他保護

Django 還提供其他形式的保護(其中大部分難以演示或不特別有用)

SQL 注入保護

SQL 注入漏洞使惡意使用者能夠在資料庫上執行任意 SQL 程式碼,從而允許訪問、修改或刪除資料,而無論使用者的許可權如何。在幾乎所有情況下,您都將使用 Django 的查詢集/模型訪問資料庫,因此生成的 SQL 將由底層資料庫驅動程式正確轉義。如果您確實需要編寫原始查詢或自定義 SQL,那麼您需要明確考慮防止 SQL 注入。

點選劫持保護

在此攻擊中,惡意使用者劫持了針對可見頂級站點的點選,並將其路由到其下方隱藏的頁面。例如,此技術可能用於顯示合法的銀行站點,但在攻擊者控制的不可見的 <iframe> 中捕獲登入憑據。Django 包含 點選劫持 保護,形式為 X-Frame-Options 中介軟體,在支援的瀏覽器中,它可以阻止站點在框架內呈現。

強制使用 TLS/HTTPS

可以在 Web 伺服器上啟用 TLS/HTTPS,以加密站點和瀏覽器之間的所有流量,包括否則將以純文字形式傳送的身份驗證憑據(強烈建議啟用 HTTPS)。如果啟用了 HTTPS,Django 還提供了一些您可以使用的其他保護措施

主機頭驗證

使用ALLOWED_HOSTS僅接受來自受信任主機的請求。

還有許多其他保護措施,以及上述機制使用的注意事項。雖然我們希望這能讓您大致瞭解 Django 的功能,但您仍然應該閱讀 Django 安全文件。

總結

Django 對許多常見威脅(包括 XSS 和 CSRF 攻擊)具有有效的防護。在本文中,我們演示了 Django 在我們的 LocalLibrary 網站中如何處理這些特定威脅。我們還簡要概述了一些其他保護措施。

這只是對網路安全的一次非常簡短的探討。我們強烈建議您閱讀Django 中的安全以獲得更深入的理解。

本模組關於 Django 的下一個也是最後一個步驟是完成評估任務

另見