Django 安全性與防禦性編程:如何保護 Django Web 應用

来源:https://www.cnblogs.com/Amd794/p/18189963
-Advertisement-
Play Games

title: Django 安全性與防禦性編程:如何保護 Django Web 應用 date: 2024/5/13 20:26:58 updated: 2024/5/13 20:26:58 categories: 後端開發 tags: CSRF XSS SQL Upload HTTPOnly Pa ...



title: Django 安全性與防禦性編程:如何保護 Django Web 應用
date: 2024/5/13 20:26:58
updated: 2024/5/13 20:26:58
categories:

  • 後端開發

tags:

  • CSRF
  • XSS
  • SQL
  • Upload
  • HTTPOnly
  • Password
  • Session

image

跨站請求偽造(CSRF)

跨站請求偽造(CSRF)是一種常見的網路攻擊,它利用用戶的身份和許可權,欺騙伺服器執行非預期的操作。Django 提供了一種內置的 CSRF 保護機制,可以幫助保護應用免受 CSRF 攻擊。

Django 的 CSRF 保護機制是通過 CSRF 令牌(CSRF Token)實現的,它是一個加密字元串,包含了一些關於用戶會話和請求的信息。在每個 POST、PUT、PATCH 和 DELETE 請求中,都需要在表單或 AJAX 請求中包含這個 CSRF 令牌,以便伺服器可以驗證請求的合法性。
AD:首頁 | 一個覆蓋廣泛主題工具的高效線上平臺
在 Django 中,可以通過以下幾種方式獲取 CSRF 令牌:

  1. 在 HTML 模板中,使用 {% csrf_token %} 標簽,在表單中插入 CSRF 令牌。

    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">提交</button>
    </form>
    
  2. 在 AJAX 請求中,可以從 csrfmiddlewaretoken 的 cookie 中獲取 CSRF 令牌,併在請求頭中添加 X-CSRFToken 欄位。

    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = cookies[i].trim();
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    
    function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    
    $.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
            }
        }
    });
    
  3. 在 Django 視圖函數中,可以使用 request.META 獲取 CSRF 令牌,併在請求中驗證它的合法性。

    from django.middleware.csrf import get_token
    
    def my_view(request):
        token = get_token(request)
        # ...
        if request.method == 'POST':
            # ...
            if not request.is_csrf_token_valid():
                return HttpResponseBadRequest('Invalid CSRF token.')
    

Django 的 CSRF 保護機制可以幫助開發人員快速實現安全的 Web 應用,但是也需要註意一些問題,例如在使用 AJAX 請求時,需要確保請求頭中包含了 CSRF 令牌,否則伺服器會拒絕處理該請求。同時,在使用 CSRF 令牌時,也需要註意防止 CSRF 令牌被泄露,例如在表單中使用 HTTP GET 方法時,需要註意 CSRF 令牌的隱藏性。

AD:專業搜索引擎
總之,Django 的 CSRF 保護機制是一個強大的工具,可以幫助開發人員快速實現安全的 Web 應用,但是也需要註意一些問題,以確保 CSRF 令牌的安全性。

跨站腳本(XSS)

跨站腳本(XSS,Cross-site Scripting)攻擊是一種常見的網路安全威脅,攻擊者通過註入惡意腳本到用戶的瀏覽器中,來竊取用戶的敏感信息或者執行非授權操作。Django 提供了一套內置的安全特性來幫助防止 XSS 攻擊,其中包括過濾器(filters)和模板標簽(template tags)。

  1. 內置過濾器: Django 的模板引擎(如 Django 的 {{ }} 模板標簽)提供了 safe 過濾器,用於標記字元串為安全的,不會進行 HTML 實體轉義。當需要在模板中顯示用戶輸入的內容,但不想進行轉義時,可以使用 safe 過濾器。

    <p>{{ user_input|safe }}</p>
    

    如果 user_input 可能包含惡意腳本,你需要確保它是可信的,或者在輸出之前進行適當的清理和驗證。

  2. 模板標簽: Django 提供了 safe 標簽,可以將整個塊標記為安全,不會進行轉義。

    {% autoescape off %}
    <p>{{ user_input|safe }}</p>
    {% endautoescape %}
    

    這裡 autoescape off 指令關閉了模板的自動轉義功能,如果在塊內部使用 safe 標簽,可以確保用戶輸入不會被轉義。

  3. Content Security Policy (CSP) : Django 的 django.middleware.clickjacking.XSSMiddleware 和 django.middleware.security.SecurityMiddleware 中包含了 Content Security Policy 的支持,可以限制頁面可以載入的內容來源,防止惡意腳本的執行。

  4. HTML5 模式: Django 的 X_FRAME_OPTIONS 設置可以控制頁面是否可以嵌入到其他頁面中,防止點擊劫持(Clickjacking)攻擊,這是一種變相的 XSS 攻擊。

  5. 輸入驗證: 在接收用戶輸入時,始終進行適當的驗證和清理,確保數據的格式和內容符合預期,避免惡意腳本的註入。

儘管 Django 提供了這些內置的保護機制,但開發人員仍然需要保持警惕,因為攻擊者可能會使用各種手段繞過這些防禦。在處理用戶輸入時,始終遵循“最小許可權原則”,只允許必要的數據和功能,並且在必要時使用第三方庫(如 django-csp 或 django-xss-filter)進行額外的安全增強。

SQL註入

Django 使用 Object-Relational Mapping (ORM) 技術,可以有效幫助開發人員避免 SQL 註入攻擊。ORM 是一種在應用程式中使用高級編程語言(如 Python)來操作資料庫的方法,它可以將 SQL 語句的構造轉移到框架內部,從而減少直接編寫 SQL 語句的需求。

AD:漫畫首頁
Django 的 ORM 將參數化查詢作為預設行為,這意味著在構造 SQL 語句時,用戶提供的數據會被自動轉義,避免了直接將用戶輸入拼接到 SQL 語句中,這是 SQL 註入攻擊的主要入口。

以下是使用 Django ORM 時應該遵循的安全最佳實踐:

  1. 使用 ORM 而不是原生 SQL:儘可能地使用 Django ORM 來操作資料庫,而不是直接編寫原生 SQL 語句。ORM 會幫助你自動轉義用戶輸入,避免 SQL 註入攻擊。

  2. 使用參數化查詢:當需要使用原生 SQL 時,始終使用參數化查詢,避免將用戶輸入直接拼接到 SQL 語句中。例如,使用 Django 的 execute 方法:

    from django.db import connection
    
    with connection.cursor() as cursor:
        cursor.execute("SELECT * FROM myapp_model WHERE id = %s", [user_id])
        result = cursor.fetchone()
    

    這裡,%s 是一個占位符,[user_id] 是一個列表,其中包含用戶輸入的數據,ORM 會自動將其轉義,避免 SQL 註入攻擊。

  3. 使用預定義的查詢:使用 Django ORM 提供的查詢方法,如 getfilterexclude 等,而不是直接使用原生的 SQL 查詢。這些查詢方法也會自動轉義用戶輸入,避免 SQL 註入攻擊。

  4. 輸入驗證:在接收用戶輸入時,始終進行適當的驗證和清理,確保數據的格式和內容符合預期,避免惡意輸入。

雖然 Django ORM 可以有效幫助開發人員避免 SQL 註入攻擊,但不能完全消除這種風險。因此,在處理用戶輸入時,始終應該遵循“最小許可權原則”,只允許必要的數據和功能,併在必要時使用第三方庫(如 django-sql-security)進行額外的安全增強。

文件上傳攻擊

Django 提供了一些內置的安全特性來幫助處理文件上傳,以減少文件上傳攻擊的風險。以下是一些關鍵的安全措施和最佳實踐:

  1. 文件存儲和路徑安全

    • 避免使用用戶提供的文件名:不要直接使用用戶上傳的文件名來保存文件,因為這可能導致路徑遍歷攻擊。應該生成一個隨機的文件名,並確保文件存儲在安全的目錄中。
    • 限制文件存儲位置:確保文件存儲在應用程式的受控目錄中,避免將文件存儲在可由Web伺服器直接訪問的位置,這樣可以防止直接訪問上傳的文件。
  2. 文件類型和大小限制

    • 檢查文件類型:使用 mimetypecontent_type 或文件的擴展名來驗證文件類型,確保只接受預期的文件類型。
    • 限制文件大小:在 settings.py 中設置 FILE_UPLOAD_MAX_MEMORY_SIZE 和 FILE_UPLOAD_MAX_NUMBER_PER_FIELD 來限制單個文件上傳的大小和每個表單欄位可以上傳的文件數量。
  3. 文件內容驗證

    • 檢查文件內容:對於某些文件類型(如圖像),可以使用庫(如 PIL)來檢查文件內容是否符合預期格式,以防止嵌入惡意代碼。
  4. 使用 Django 的 FileField 和 ImageField

    • 這些欄位類型提供了內置的驗證,可以檢查文件的 mimetype 和大小。
  5. 安全處理上傳的文件

    • 不要執行不可信的文件:永遠不要在伺服器上執行用戶上傳的文件,這可能導致代碼執行攻擊。
    • 隔離上傳文件:如果可能,將上傳的文件存儲在隔離的環境中,以減少潛在的安全風險。
  6. 使用 Django 的中間件和視圖

    • Django 的中間件可以用來在文件上傳到視圖之前進行額外的安全檢查。
    • 使用 Django 的視圖裝飾器,如 @login_required,來確保只有認證用戶才能上傳文件。
  7. 定期更新和安全審計

    • 定期更新 Django 和所有依賴庫,以確保使用最新的安全修複。
    • 進行安全審計,檢查文件上傳功能是否存在潛在的安全漏洞。

通過遵循這些最佳實踐,可以大大降低文件上傳攻擊的風險。然而,安全是一個持續的過程,需要不斷地評估和改進。

Django 框架支持 HTTPOnly cookie,這是一種有助於提高網站安全性的措施。HTTPOnly cookie 是一種特殊的 cookie,它通過在設置 cookie 時添加 HttpOnly 標誌來實現。這個標誌告訴瀏覽器,該 cookie 不應該通過客戶端腳本(如 JavaScript)訪問。

以下是 HTTPOnly cookie 的一些關鍵點:

  1. 防止 XSS 攻擊: HTTPOnly cookie 可以防止跨站腳本(XSS)攻擊,因為攻擊者無法通過註入惡意腳本來讀取用戶的 cookie。這有助於保護用戶的會話信息不被竊取。

  2. 增強會話安全: 當用戶登錄到一個網站時,伺服器通常會創建一個會話 cookie,用於在後續請求中識別用戶。如果這個 cookie 是 HTTPOnly 的,那麼即使網站存在 XSS 漏洞,攻擊者也無法通過 JavaScript 獲取這個 cookie。

  3. Django 中的設置: Django 預設會為 session cookie 和 CSRF token cookie 啟用 HTTPOnly 標誌。你可以在 Django 的設置文件 settings.py 中找到以下配置:

    SESSION_COOKIE_HTTPONLY = True
    CSRF_COOKIE_HTTPONLY = True
    

    這些設置確保了 Django 生成的 session cookie 和 CSRF token cookie 都是 HTTPOnly 的。

  4. 手動設置 HTTPOnly cookie: 如果你需要在 Django 視圖中手動設置 cookie,並且希望它是 HTTPOnly 的,你可以這樣做:

    response = HttpResponse()
    response.set_cookie('my_cookie', 'value', httponly=True)
    

    在這個例子中,my_cookie 將被設置為 HTTPOnly cookie。

雖然 HTTPOnly cookie 提供了額外的安全層,但它並不能完全防止所有類型的攻擊。例如,它不能防止中間人攻擊或通過其他方式(如網路嗅探)獲取 cookie。因此,除了使用 HTTPOnly cookie 之外,還應該採取其他安全措施,如使用 HTTPS、實施內容安全策略(CSP)等,以進一步提高網站的安全性。

密碼安全性

Django 提供了內置的安全密碼存儲功能,這是通過其內置的 django.contrib.auth 庫中的 User 模型和密碼哈希處理機制實現的。當用戶註冊並設置密碼時,Django並不會直接存儲明文密碼,而是存儲密碼的哈希值和一個隨機鹽值(salt)。

以下是 Django 安全密碼存儲的關鍵點:

  1. 哈希演算法: Django 使用了 bcrypt 和 PBKDF2(取決於你的 Django 版本)這樣的安全哈希演算法來加密密碼。這些演算法經過精心設計,即使攻擊者知道哈希值,也無法輕易地通過暴力破解或彩虹表來恢複原始密碼。

  2. 鹽值: 每個用戶的密碼哈希值都會與一個唯一的隨機鹽值結合,這樣即使相同的密碼,由於鹽值不同,生成的哈希值也會不同。這進一步增加了破解的難度。

  3. set_password() 方法: 當用戶設置密碼時,Django 提供了 set_password() 方法,它會自動處理密碼的哈希和鹽值生成。示例代碼如下:

    user = User.objects.create_user(username='myuser', password='mypassword')
    user.set_password('mypassword')
    user.save()
    
  4. 驗證密碼: 當用戶嘗試登錄時,Django 會計算他們提供的密碼與資料庫中存儲的哈希值和鹽值的匹配。這通過 authenticate() 函數完成,而不是直接比較密碼。

  5. check_password() 方法: 為了驗證密碼,可以使用 check_password() 方法,如:

    if user.check_password('mynewpassword'):
        # 密碼正確
    else:
        # 密碼錯誤
    

通過這種方式,Django 有效地保護了用戶的密碼,即使資料庫被泄露,攻擊者也無法直接獲取到用戶的密碼,從而提高了安全性。

安全會話

Django 使用加密和簽名的方式來保護會話數據,以確保會話的安全性。下麵是 Django 中安全會話的實現方式:

  1. 加密會話數據: Django 預設會將會話數據加密後存儲在用戶的瀏覽器中。這樣即使用戶可以查看瀏覽器的 cookie 數據,也無法直接讀取和理解其中的內容。Django 使用密鑰來加密和解密會話數據,確保數據的機密性。
  2. 簽名會話數據: 除了加密數據外,Django 還會對會話數據進行簽名。簽名是通過使用密鑰和哈希演算法來生成一個簽名值,用於驗證數據的完整性和真實性。如果會話數據在傳輸過程中被篡改,簽名驗證將失敗,從而防止數據被篡改。
  3. SESSION_ENGINE 設置: 在 Django 的設置文件中,可以通過 SESSION_ENGINE 設置來選擇會話引擎。預設情況下,Django 使用 django.contrib.sessions.backends.db 作為會話引擎,將加密和簽名的會話數據存儲在資料庫中。也可以選擇其他會話引擎,如 django.contrib.sessions.backends.cache 或 django.contrib.sessions.backends.file
  4. SESSION_COOKIE_SECURE 設置: 可以通過設置 SESSION_COOKIE_SECURE = True 來確保會話 cookie 只能通過 HTTPS 連接傳輸,增加會話數據的安全性。
  5. SESSION_COOKIE_HTTPONLY 設置: 同樣可以通過設置 SESSION_COOKIE_HTTPONLY = True 來禁止 JavaScript 訪問會話 cookie,減少 XSS 攻擊的可能性。

通過加密和簽名會話數據,Django 確保了用戶的會話信息在傳輸和存儲過程中的安全性,防止敏感數據泄露和篡改。這是保護用戶隱私和確保系統安全的重要措施之一。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 引言 有這麼一個需求:列表頁進入詳情頁後,切換回列表頁,需要對列表頁進行緩存,如果從首頁進入列表頁,就要重新載入列表頁。 對於這個需求,我的第一個想法就是使用keep-alive來緩存列表頁,列表和詳情頁切換時,列表頁會被緩存;從首頁進入列表頁時,就重置列表頁數據並重新獲取新數據來達到列表頁重新載入 ...
  • 在當今的信息時代,無線通信技術的發展日新月異,為我們的工作和生活帶來了極大的便利。其中,無線通信模塊通過TCP/IP協議向PC端傳送數據已經成為了一種常見的通信方式。本文將詳細介紹這一過程的主要步驟和涉及的關鍵技術,並以WIFI模塊為例,探討如何在QT平臺下實現數據的無線傳輸。 一、無線通信模塊與T ...
  • 前言 MVC,MVP,MVVM 屬於 GUI 軟體設計,它們都強調將軟體的視圖顯示與業務邏輯進行分離,將軟體拆分為三個部分,分別負責數據操作、視圖邏輯、業務邏輯。 業務邏輯指的是任何與數據操作、視圖操作的定義與實現無關的功能。 具體來說,業務邏輯中不應該出現如何操作視圖或如何操作數據的細節。 對於這 ...
  • X-Frame-Options 是一個HTTP響應頭,用於控制網頁是否可以嵌套在 <frame>, <iframe>, <embed> 或者 <applet> 中。通過設置 X-Frame-Options 頭部,網站管理員可以防止網頁被嵌套到其他網站的框架中,從而有效防範點擊劫持等安全風險。下麵是關 ...
  • nginx 系列 Nginx-01-聊一聊 nginx Nginx-01-Nginx 是什麼 Nginx-02-為什麼使用 Nginx Nginx-02-Nginx Ubuntu 安裝 + windows10 + WSL ubuntu 安裝 nginx 實戰筆記 Nginx-02-基本使用 Ngin ...
  • JPEG庫的移植(arm平臺) 目錄JPEG庫的移植(arm平臺)介紹頭文件及全局變數1、圖片顯示2、其他圖片壓縮到jpg圖片3、主函數及驗證程式輸出結果 介紹 圖解 頭文件及全局變數 #include <stdio.h> #include <stdlib.h> #include <sys/type ...
  • 寫在前面 這部分真的感覺超級難,其實也不能說難,主要是真的想不到這個思路應該這麼做,或者說他好厲害,他怎麼知道該這麼設計實現。 說下難點吧,我覺得後天邏輯還好,主要是前端部分真的需要點花點時間來思考,比如佈局、交互設計的實現等等。 文檔頁面功能開發 1、任務拆解 增加文檔頁面,首頁點擊電子書時,跳轉 ...
  • NumPy 數組的複製與視圖 NumPy 數組的複製和視圖是兩種不同的方式來創建新數組,它們之間存在著重要的區別。 複製 複製 會創建一個包含原始數組相同元素的新數組,但這兩個數組擁有獨立的記憶體空間。這意味著對複製進行的任何更改都不會影響原始數組,反之亦然。 創建副本可以使用以下方法: arr.co ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...