Kali Linux Web 滲透測試秘籍 第十章 OWASP Top 10 的預防

第十章 OWASP Top 10 的預防

作者:Gilberto Najera-Gutierrez

譯者:飛龍

協議:CC BY-NC-SA 4.0

簡介

每個滲透測試的目標都是識別應用、服務器或網絡中的可能缺陷,它們能夠讓攻擊者有機會獲得敏感系統的信息或訪問權限。檢測這類漏洞的原因不僅僅是了解它們的存在以及推斷出其中的漏洞,也是為了努力預防它們或者將它們降至最小。

這一章我們,我們會觀察一些如何預防多數 Web 應用漏洞的例子和推薦,根據 OWASP:

https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project

A1 預防注入攻擊

根據 OWASP,Web 應用中發現的最關鍵的漏洞類型就是一些代碼的注入攻擊,例如 SQL 注入、OS 命令注入、HTML 注入(XSS)。

這些漏洞通常由應用的弱輸入校驗導致。這個秘籍中,我們會設計一些處理用戶輸入和構造所使用的請求的最佳實踐。

操作步驟

  1. 為了防止注入攻擊,首先需要合理校驗輸入。在服務端,這可以由編寫我們自己的校驗流程來實現,但是最佳選擇是使用語言自己的校驗流程,因為它們更加廣泛使用并測試過。一個極好的激勵就是 PHP 中的filter_var,或者 ASP.NET 中的 校驗助手。例如,PHP 中的郵箱校驗類似于:

    function isValidEmail($email){ 
        return filter_var($email, FILTER_VALIDATE_EMAIL); 
    }
    
  2. 在客戶端,檢驗可以由創建 JavaScript 校驗函數來完成,使用正則表達式。例如,郵箱檢驗流程是:

    function isValidEmail (input) { 
        var result=false; 
        var email_regex = /^[a-zA-Z0-9._-]+@([a-zA-Z0-9.-]+\.)+[azA-Z0-9.-]{2,4}$/; 
        if ( email_regex.test(input) ) {  
            result = true; 
        } 
        return result; 
    }
    
  3. 對于 SQL 注入,避免拼接輸入值為查詢十分關鍵。反之,使用參數化查詢。每個編程語言都有其自己的版本:

    PHP MySQLLi:

    $query = $dbConnection->prepare('SELECT * FROM table WHERE name = ?'); 
    $query->bind_param('s', $name); 
    $query->execute(); 
    

    C#:

    string sql = "SELECT * FROM Customers WHERE CustomerId = @ CustomerId"; 
    SqlCommand command = new SqlCommand(sql); command.Parameters.Add(new SqlParameter("@CustomerId", System. Data.SqlDbType.Int)); 
    command.Parameters["@CustomerId"].Value = 1; 
    

    Java:

    String custname = request.getParameter("customerName"); 
    String query = "SELECT account_balance FROM user_data WHERE user_ name =? ";  
    PreparedStatement pstmt = connection.prepareStatement( query ); 
    pstmt.setString( 1, custname); 
    ResultSet results = pstmt.executeQuery( ); 
    
  4. 考慮注入出現的時機,對減少可能的損失總量也有幫助。所以,使用低權限的系統用戶來運行數據庫和 Web 服務器。

  5. 確保輸入用于連接數據庫服務器的用戶不是數據庫管理員。

  6. 禁用甚至刪除允許攻擊者執行系統命令或提權的儲存過程,例如 MSSQL 服務器中的xp_cmdshell

工作原理

預防任何類型代碼注入攻擊的主要部分永遠是合理的輸入校驗,位于服務端也位于客戶端。

對于 SQL 注入,始終使用參數化或者預編譯查詢。而不是拼接 SQL 語句和輸入。參數化查詢將函數參數插入到 SQL 語句特定的位置,消除了程序員通過拼接構造查詢的需求。

這個秘籍中,我們使用了語言內建的校驗函數,但是如果你需要校驗一些特殊類型的參數,你可以通過使用正則表達式創建自己的版本。

除了執行正確校驗,我們也需要在一些人蓄意注入一些代碼的情況下,降低淪陷的影響。這可以通過在操作系統的上下文中為 Web 服務器合理配置用戶權限,以及在數據庫服務器上下文中配置數據庫和 OS 來實現。

另見

對于數據校驗來講,最有用的工具就是正則表達式。在處理和過濾大量信息的時候,它們也能夠讓滲透測試變得更容易。所以好好了解它們很有必要。我推薦你查看一些站點:

A2 構建合理的身份驗證和會話管理

帶有缺陷的身份驗證和會話管理是當今 Web 應用中的第二大關鍵的漏洞。

身份驗證是用戶證明它們是它們所說的人的過程。這通常通過用戶名和密碼來完成。一些該領域的常見缺陷是寬松的密碼策略,以及隱藏式的安全(隱藏資源缺乏身份驗證)。

會話管理是登錄用戶的會話標識符的處理。在 Web 服務器中,這可以通過實現會話 Cookie 和標識來完成。這些標識符可以植入、盜取,或者由攻擊者使用社會工程、XSS 或 CSRF 來“劫持”。所以,開發者必須特別注意如何管理這些信息。

這個秘籍中,我們會設計到一些實現用戶名/密碼身份驗證,以及管理登錄用戶的會話標識符的最佳實踐。

操作步驟

  1. 如果應用中存在只能由授權用戶查看的頁面、表單或者任何信息片段,確保在展示它們之前存在合理的身份驗證。

  2. 確保用戶名、ID、密碼和所有其它身份驗證數據是大小寫敏感的,并且對每個用戶唯一。

  3. 建立強密碼策略,強迫用戶創建至少滿足下列條件的密碼:

    • 對于 8 個字符,推薦 10 個。

    • 使用大寫和小寫字母。

    • 至少使用一個數字。

    • 至少使用一個特殊字符(空格、!&#%,以及其它)。

    • 禁止用戶名、站點名稱、公司名稱或者它們的變體(大小寫轉換、l33t、它們的片段)用于密碼。

    • 禁止使用“常見密碼”列表中的密碼:https://www.teamsid.com/worst-passwords-2015/

    • 永遠不要顯示用戶是否存在或者信息格式是否正確的錯誤信息。對不正確的登錄請求、不存在的用戶、名稱或密碼不匹配模式、以及所有可能的登錄錯誤使用相同的泛化信息。這種信息類似于:

      登錄數據不正確。

      用戶名或密碼無效。

      訪問禁止。

  4. 密碼不能以純文本格式儲存在數據庫中。使用強哈希算法,例如 SHA-2、scrypt、或者 bcrypt,它們特別為難以使用 GPU 破解而設計。

  5. 在對比用戶輸入和密碼時,計算輸入的哈希之后比較哈希之后的字符串。永遠不要解密密碼來使用純文本用戶輸入來比較。

  6. 避免基本的 HTML 身份驗證。

  7. 可能的話,使用多因素驗證(MFA),這意味著使用不止一個身份驗證因素來登錄:

    • 一些你知道的(賬戶信息或密碼)

    • 一些你擁有的(標識或手機號)

    • 一些你的特征(生物計量)

  8. 如果可能的話,實現證書、預共享密鑰、或其它無需密碼的身份校驗協議(OAuth2、OpenID、SAML、或者 FIDO)。

  9. 對于會話管理,推薦使用語言內建的會話管理系統,Java、ASP.NET和 PHP。它們并不完美,但是能夠確保提供設計良好和廣泛測試的機制,而且比起開發團隊在時間緊迫情況下的自制版本,它們更易于實現。

  10. 始終為登錄和登錄后的頁面使用 HTTPS -- 顯然,要防止只接受 SSL 和 TLS v1.1 連接。

  11. 為了確保 HTTPS 能夠生效,可以使用 HSTS。它是由 Web 應用指定的雙向選擇的特性。通過 Strict-Transport-Security 協議頭,它在 http://存在于 URL 的情況下會重定向到安全的選項,并防止“無效證書”信息的覆寫。例如使用 Burp Suite 的時候會出現的情況。更多信息請見: https://www.owasp.org/index.php/HTTP_Strict_Transport_Security

  12. 始終設置 HTTPOnly 和安全的 Cookie 屬性。

  13. 設置最少但實際的會話過期時間。確保正常用戶離開之后,攻擊者不能復用會話,并且用戶能夠執行應用打算執行的操作。

工作原理

身份校驗機制通常在 Web 應用中簡化為用戶名/密碼登錄頁面。雖然并不是最安全的選擇,但它對于用戶和開發者最簡單,以及當密碼被盜取時,最重要的層面就是它們的強度。

我們可以從這本書看到,密碼強度由破解難度決定,通過爆破、字典或猜測。這個秘籍的第一個提示是為了使密碼更難以通過建立最小長度的混合字符集來破解,難以通過排除更直覺的方案(用戶名、常見密碼、公司名稱)來猜測,并且通過使用強哈希或加密儲存,難以在泄露之后破解。

對于會話管理來說,過期時間、唯一性和會話 ID 的強度(已經在語言內建機制中實現),以及 Cookie 設置中的安全都是關鍵的考慮因素。

談論身份校驗安全的最重要的層面是,如果消息可以通過中間人攻擊攔截或者服務,沒有任何安全配置、控制或強密碼是足夠安全的。所以,合理配置的加密通信頻道的使用,例如 TLS,對保護我們的用戶身份數據來說極其重要。

另見

OWASP 擁有一些非常好的頁面,關于身份校驗和會話管理。我們推薦你在構建和配置 Web 應用時閱讀并仔細考慮它們。

A3 預防跨站腳本

我們之前看到,跨站腳本,在展示給用戶的數據沒有正確編碼,并且瀏覽器將其解釋并執行為腳本代碼時發生。這也存在輸入校驗因素,因為惡意代碼通常由輸入變量插入。

這個秘籍中,我們會涉及開發者所需的輸入校驗和輸出編碼,來防止應用中的 XSS 漏洞。

工作原理

  1. 應用存在 XSS 漏洞的第一個標志是,頁面準確反映了用戶提供的輸入。所以,嘗試不要使用用戶提供的信息來構建輸出文本。

  2. 當你需要將用戶提供的信息放在輸出頁面上時,校驗這些數據來防止任何類型代碼的插入。我們已經在 A1 中看到如何實現它。

  3. 出于一些原因,如果用戶被允許輸入特殊字符或者代碼段,在它插入到輸出之前,過濾或合理編碼文本。

  4. 對于過濾,在 PHP 中,可以使用filter_var。例如,如果你想讓字符串為郵件地址:

    $email = "john(.doe)@exa//mple.com"; 
    $email = filter_var($email, FILTER_SANITIZE_EMAIL); 
    echo $email;
    

    對于編碼,你可以在 PHP 中使用htmlspecialchars

    $str = "The JavaScript HTML tags are <script> for opening, and </ script>  for closing."; 
    echo htmlspecialchars($str); 
    
  5. 在 .NET 中,對于 4.5 及更高版本,System.Web.Security.AntiXss命名空間提供了必要的工具。對于 .NET 框架 4 及之前的版本,你可以使用 Web 保護庫:http://wpl.codeplex.com/

  6. 同樣,為了防止儲存型 XSS,在儲存進數據庫或從數據庫獲取之前,編碼或過濾每個信息片段。

  7. 不要忽略頭部、標題、CSS和頁面的腳本區域,因為它們也可以被利用。

工作原理

除了合理的輸入校驗,以及不要將用戶輸入用作輸出信息,過濾和編碼也是防止 XSS 的關鍵層面。

過濾意味著從字符串移除不允許的字符。這在輸入字符串中存在特殊字符時很實用。

編碼將特殊字符轉換為 HTML 代碼表示。例如,&變為&amp;<變為&lt;。一些應用允許在輸入字符串中使用特殊字符,對它們來說過濾不是個選擇。所以應該在將輸入插入頁面,或者儲存進數據庫之前編碼輸入。

另見

OWASP 擁有值得閱讀的 XSS 預防速查表:

A4 避免直接引用不安全對象

當應用允許攻擊者(也是校驗過的用戶)僅僅修改請求中的,直接指向系統對象的參數值,來訪問另一個未授權的對象時,就存在不安全對象的直接引用(IDOR)。我們已經在本地文件包含和目錄遍歷漏洞中看到了一些例子。

根據 OWASP,IDOR 是 Web 應用中第四大關鍵漏洞。這些漏洞通常由不良的訪問控制實現,或者“隱藏式安全”策略(如果用戶不能看到它,他們就不能知道它的存在)導致。這些在沒有經驗的開發者之中是個常見的做法。

這個秘籍中,我們會涉及在設計訪問控制機制時應該考慮的關鍵層面,以便預防 IDOR 漏洞。

操作步驟

  1. 使用非直接引用優于直接引用。例如,不要通過參數中的名稱來引用頁面(URL?page="restricted_page"),而是要創建索引,并在內部處理它(URL?page=2)。

  2. 將非直接引用映射到用戶(會話)層面,于是用戶僅僅能夠訪問授權的對象,即使它們修改了下標。

  3. 在傳遞相應對象之前校驗引用,如果請求的用戶沒有權限來訪問,展示通用錯誤頁面。

  4. 輸入校驗也是很重要的,尤其是目錄遍歷和文件包含的情況下。

  5. 永遠不要采取“隱藏式安全”的策略。如果有些文件包含受限的信息,即使它沒有引用,有些人也會把它翻出來。

工作原理

不安全對象的直接引用在 Web 應用中的表現形式有所不同,從目錄遍歷到敏感的 PDF 文檔的引用。但是它們的大多數都依賴于一個假設,即用戶永遠不會找到方法來訪問不能顯式訪問的東西。

為了防止這種漏洞,需要在設計和開發期間執行一些積極操作。設計可靠授權機制,來驗證嘗試訪問一些信息的用戶的關鍵是,是否用戶真正允許訪問它。

將引用對象映射為下標來避免對象名稱直接用于參數值(就像 LFI 中的那樣)是第一步。攻擊者也可以修改下標,這很正常,就像對對象名稱所做的那樣。但是數據庫中存在下標-對象的表的話,添加字段來規定訪問所需的權限級別,比起沒有任何表并且直接通過名稱來訪問資源,要容易得多。

之前說過,下標的表可能包含訪問對象所需的權限級別,更加嚴格的話還有擁有者的 ID。所以,它只能夠在請求用戶是擁有者的情況下訪問。

最后,輸入校驗必須存在于 Web 應用安全的每個層面。

A5 基本的安全配置指南

系統的默認配置,包括操作系統和Web 服務器,多數用于演示和強調他們的基本或多數有關特性,并不能保護它們不被攻擊。

一些常見的可能使系統淪陷的默認配置,是數據庫、Web 服務器或CMS 安裝時創建的默認管理員賬戶,以及默認管理員頁面、默認棧回溯錯誤信息,以及其它。

這個秘籍中,我們會涉及 OWASP Top 10 中第五大關鍵漏洞,錯誤的安全配置。

操作步驟

  1. 可能的話,刪除所有管理員應用,例如 Joomla 的 admin,WordPress 的 admin,PhpMyAdmin,或者 Tomcat Manager。如果不能這樣,使它們只能從本地網絡訪問,例如,在 Apache 服務器中禁止來自外部網絡的 PhpMyAdmin 訪問,修改httd.conf文件(或者相應的站點配置文件)。

    <Directory /var/www/phpmyadmin>
    
        Order Deny,Allow  
        Deny from all  
        Allow from 127.0.0.1 ::1  
        Allow from localhost  
        Allow from 192.168  
        Satisfy Any
        
    </Directory>
    

    這會首先禁止所有地址到phpmyadmin目錄的訪問,之后它允許任何來自 locaohost 和以192.168開頭的地址的請求,這是本地網絡的地址。

  2. 修改所有 CMS、應用、數據庫、服務器和框架的所有管理員密碼,使其強度足夠。一些應用的例子是:

    • Cpanel
    • Joomla
    • WordPress
    • PhpMyAdmin
    • Tomcat manager
  3. 禁用所有不必要或未使用的服務器和應用特性。從日常或每周來看,新的漏洞都出現在 CMS 的可選模塊和插件中。如果你的應用不需要它們,就不要激活它們。

  4. 始終執行最新的安全補丁和更新。在生成環境,建立測試環境來預防使站點不工作的缺陷十分重要,因為新版本存在一些兼容性及其它問題。

  5. 建立不會泄露跟蹤信息、軟件版本、程序組件名稱,或任何其它調試信息的自定義的錯誤頁面。如果開發者需要跟蹤錯誤記錄或者一些一些標識符對于技術支持非常必要,創建帶有簡單 ID 和錯誤描述的索引,并只展示 ID 給用戶。所以當錯誤報告給相關人士的時候,它們會檢查下標并且知道發生了什么錯誤。

  6. 采取“最小權限原則”。每個用戶在每個層面(操作系統、數據庫、或應用)上都應該只能夠嚴格訪問正確操作所需的信息。

  7. 使用上一個要點來考慮賬戶,構建安全配置的原則,并且將其應用到每個新的實現、更新或發布以及當前系統中。

  8. 強制定期的安全測試或審計,來幫助檢測錯誤配置或遺漏的補丁。

工作原理

談論安全和配置問題時,“細節決定成敗”十分恰當。web 服務器、數據庫服務器、CMS、或者應用配置應該在完全可用和實用、以及保護用戶和擁有者之間取得平衡。

Web 應用的一個常見錯誤配置就是一些 Web 管理站點對整個互聯網都可見。這看起來并不是個大問題,但是我們應該知道,管理員登錄頁面更容易吸引攻擊者,因為它可以用于獲得高級權限等級,并且任何 CMS、數據或者站點管理工具都存在已知的常用默認密碼列表。所以,我們強烈推薦不要把這些管理站點暴露給外部,并且盡可能移除它們。

此外,強密碼的使用,以及修改默認密碼(即使它們是強密碼),在發布應用到公司內部網絡,以及互聯網的時候需要強制執行。當今,當我們將服務器開放給外部的時候,它收到的第一個流量就是端口掃描,登錄頁面請求,以及登錄嘗試,甚至在第一個用戶知道該應用之前。

自定義錯誤頁面的使用有助于安全準備,因為 Web 服務器和應用中的默認的錯誤信息展示太多的信息(從攻擊者角度),它們關于錯誤、所使用的編程語言、棧回溯、所使用的數據庫、操作系統以及其它。這些信息不應該暴露,因為它會幫助我們理解應用如何構建,并且提供所使用軟件的版本和名稱。攻擊者通過這些信息就可以搜索已知漏洞,并構造更加有效的攻擊過程。

一旦我們的服務器上的部署應用和所有服務都正確配置,我們就可以制訂安全原則并且將其應用于所有要配置的新服務器或者已更新的服務器,或者當前帶有合理規劃的生產服務器。

這個配置原則需要持續測試,以便改進它以及持續保護新發現的漏洞。

A6 保護敏感數據

當應用儲存或使用敏感信息(信用卡號碼、社會安全號碼、健康記錄,以及其它)時,必須采取特殊的手段來保護它們,因為它可能為負責保護它們的組織帶來嚴重的信用、經濟或者法律損失,以及被攻破。

OWASP Top 10 的第六名是敏感數據泄露,它發生在應該保護的數據以純文本泄露,或者帶有弱安全措施的時候。

這個秘籍中,我們會涉及一些處理、傳遞和儲存這種數據類型的最佳實踐。

操作步驟

  1. 如果你使用的敏感數據可以在使用之后刪除,那么刪除它。最好每次使用信用卡的時候詢問用戶,避免被盜取。

  2. 在處理支付的時候,始終使用支付網關,而不是在你的服務器中儲存數據。查看:http://ecommerce-platforms.com/ ecommerce-selling-advice/choose-payment-gateway-ecommerce-store

  3. 如果我們需要儲存敏感數據,我們要采取的第一個保護就是使用強密碼算法和相應的強密鑰來加密。推薦 Twofish、AES、RSA 和三重 DES。

  4. 密碼儲存在數據庫的時候,應該以單項哈希函數的哈希形式存儲,例如,bcypt、scrypt 或 SHA-2。

  5. 確保所有敏感文檔只能被授權用戶訪問。不要在 Web 服務器的文檔根目錄儲存它們,而是在外部目錄儲存,并通過程序來訪問。如果出于某種原因必須在服務器的文檔根目錄儲存敏感文件,使用.htaccess文件來防止直接訪問:

    Order deny,allow 
    Deny from all
    
  6. 禁用包含敏感數據的頁面緩存。例如,在 Apache 中我們可以禁用 PDF 和 PNG 的緩存,通過httpd.conf中的下列設置:

    <FilesMatch "\.(pdf|png)> 
    FileETag None 
    Header unset ETag 
    Header set Cache-Control "max-age=0, no-cache, no-store, mustrevalidate" 
    Header set Pragma "no-cache" 
    Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT" 
    </FilesMatch>
    
  7. 如果你允許文件上傳,始終使用安全的通信頻道來傳輸敏感數據,也就是帶有 TLS 的 HTTPS,或者 FTPS(SSH 上的 FTP)。

工作原理

對于保護敏感數據,我們需要最小化數據泄露或交易的風險。這就是正確加密儲存敏感數據,以及保護加密密鑰是所做的第一件事情的原因。如果可能不需要儲存這類數據,這只是個理想選擇。

密碼應該使用單向哈希算法,在將它們儲存到數據之前計算哈希。所以,即使它們被盜取,攻擊者也不能立即使用它們,并且如果密碼強度足夠,哈希也是足夠強的算法,它就不會在短時間內被破解。

如果我們在 Apache 服務器的文檔根目錄(/var/ www/html/)儲存敏感文檔或數據,我們就通過 URL 將這些信息暴露用于下載。所以,最好將它儲存到別的地方,并編寫特殊的服務端代碼來在必要時獲取它們,并帶有預先的授權檢查。

此外,例如 Archive.org、WayBackMachine 或者 Google 緩存頁面,可能在緩存含有敏感信息的文件時,以及我們沒能在應用的上一個版本有效保護它們時產生安全問題。所以,不允許緩存此類文檔非常重要。

A7 確保功能級別的訪問控制

功能級別的訪問控制是訪問控制的一種,用于防止匿名者或未授權用戶的功能調用。根據 OWASP,缺乏這種控制是 Web 應用中第七大嚴重的安全問題。

這個秘籍中,我們會看到一些推薦來提升我們的應用在功能級別上的訪問控制。

操作步驟

  1. 確保每一步都正確檢查了工作流的權限。

  2. 禁止所有默認訪問,之后在顯示的授權校驗之后允許訪問。

  3. 用戶、角色和授權應該在靈活的媒介中儲存,例如數據庫或者配置文件,不要硬編碼它們。

  4. 同樣,“隱藏式安全”不是很好的策略。

工作原理

開發者只在工作流的開始檢查授權,并假設下面的步驟都已經對用戶授權,這是常見的現象。攻擊者可能會嘗試調用某個功能,它是工作流的中間步驟,并由于控制缺失而能夠訪問它。

對于權限,默認禁止所有用戶是個最佳實踐。如果我們不知道一些用戶是否有權訪問一些功能,那么它們就不應該執行。將你的權限表轉化為授權表。如果某些用戶在某些功能上沒有顯式的授權,則禁止它們的訪問。

在為你的應用功能構建或實現訪問控制機制的時候,將所有授權儲存在數據庫中,或者在配置文件中(數據庫是最好的選項)。如果用戶角色和權限被硬編碼,它們就會難以維護、修改或更新。

A8 防止 CSRF

當 Web 應用沒有使用會話層面或者操作層面的標識,或者標識沒有正確實現的時候,它們就可能存在跨站請求偽造漏洞,并且攻擊者可以強迫授權用戶執行非預期的操作。

CSRF 是當今 Web 應用的第八大嚴重漏洞,根據 OWASP, 并且我們在這個秘籍中會看到如何在應用中防止它。

操作步驟

  1. 第一步也是最實際的 CSRF 解決方案就是實現唯一、操作層面的標識。所以每次用戶嘗試執行某個操作的時候,會生成新的標識并在服務端校驗。

  2. 唯一標識應該不能被輕易由攻擊者猜測,所以它們不能將其包含在 CSRF 頁面中。隨機生成是個好的選擇。

  3. 在每個可能為 CSRF 目標的表單中包含要發送的標識。“添加到購物車”請求、密碼修改表單、郵件、聯系方式或收貨信息管理,以及銀行的轉賬頁面都是很好的例子。

  4. 標識應該在每次請求中發送給服務器。這可以在 URL 中實現,或者任何其它變量或者隱藏字段,都是推薦的。

  5. 驗證碼的使用也可以防止 CSRF。

  6. 同樣,在一些關鍵操作中詢問重新授權也是個最佳實踐,例如,銀行應用中的轉賬操作。

工作原理

防止 CSRF 完全是確保驗證過的用戶是請求操作的人。由于瀏覽器和 Web 應用的工作方式,最佳實踐是使用標識來驗證操作,或者可能的情況下使用驗證碼來控制。

由于攻擊者打算嘗試破解標識的生成,或者驗證系統,以一種攻擊者不能猜測的方式,安全地生成它們非常重要。而且要使它們對每個用戶和每個操作都唯一,因為復用它們會偏離它們的目的。

驗證碼控制和重新授權有時候會非常麻煩,使用戶反感。但是如果操作的重要性值得這么做,用戶可能愿意接受它們來換取額外的安全級別。

另見

有一些編程庫有助于實現 CSRF 防護,節省開發者的大量工作。例子之一就是 OWASP 的 CSRF Guard:https://www.owasp.org/index.php/CSRFGuard

A9 在哪里尋找三方組件的已知漏洞

現在的 Wbe 應用不再是單個開發者,也不是單個開發團隊的作品。開發功能性、用戶友好、外觀吸引人的 Web 應用涉及到三方組件的使用,例如編程庫,外部服務的 API(Fackbook、Google、Twitter),開發框架,以及許多其它的組件,其中編程、測試和打補丁的工作量很少,甚至沒有。

有時候這些三方組件被發現存在漏洞,并且它們將這些漏洞轉移到了我們的應用中。許多帶有漏洞組件的應用很長時間都沒有打補丁,使整個組織的安全體系中出現缺陷。這就是 OWASP 將使用帶有已知漏洞的三方組件劃分為 Web 應用安全的第九大威脅的原因。

這個秘籍中,我們會了解,如果一些我們所使用的組件擁有已知漏洞,應該到哪里尋找,以及我們會查看一些這種漏洞組件的例子。

操作步驟

  1. 第一個建議是,優先選擇受支持和廣泛使用的知名軟件。

  2. 為你的應用所使用的三方組件保持安全更新和補丁的更新。

  3. 用于搜索一些特定組件的漏洞的好地方就是廠商的網站:它們通常擁有“發布說明”部分,其中它們會公布它們糾正了哪個 bug 或漏洞。這里我們可以寸照我們所使用的(或更新的)版本,并且插件是否有有已知的問題沒有打補丁。

  4. 同樣,廠商通常擁有安全建議站點,例如 Microsoft:https://technet.microsoft.com/library/security/,Joomla:https:// developer.joomla.org/security-centre.html,和Oracle:http://www. oracle.com/technetwork/topics/security/alerts-086861.html。我們可以使用它們來保持我們用于應用的軟件的更新。

  5. 也有一些廠商無關的站點,它們致力于通知我們漏洞和安全問題。有個非常好的網站,集中了多個來源的信息,是 CVE Details(http://www.cvedetails.com/)。這里我們可以搜索多數廠商或產品,或者列出所有已知漏洞(至少是擁有 CVE 號碼的漏洞),并且按照年份、版本和 CVSS 分數排列。

  6. 同時,黑客發布利用和發現的站點也是個獲得漏洞和我們所使用的軟件的信息的好地方。最流行的是 Exploit DB(https://www.exploit-db.com/)。 Full disclosure 郵件列表(http://seclists.org/fulldisclosure/),以及 Packet Storm 的文件部分(https://packetstormsecurity.com/files/)。

  7. 一旦我們發現了我們軟件組件中的漏洞,我們必須評估它是否對我們的應用必要,或者需要移除。如果不能這樣,我們需要盡快打補丁。如果沒有可用的補丁或變通方案,并且漏洞是高危的,我們必須開始尋找組件的替代。

工作原理

考慮在我們的應用中使用三方軟件組件之前,我們需要查看它的安全信息,并了解,我們所使用的組件是否有更穩定更安全的版本或替代。

一旦我們選擇了某個,并且將其包含到我們的應用中,我們需要使其保持更新。有時它可能涉及到版本改動以及沒有后向兼容,但是這是我們想要維持安全的代價。如果我們不能更新或為高危漏洞打補丁,我們還可以使用 WAF(Web 應用防火墻)和IPS(入侵檢測系統)來防止攻擊。

除了在執行滲透測試的時候比較實用,下載和漏洞發布站點可以被系統管理員利用,用于了解可能出現什么攻擊,它們的原理,以及如何保護應用避免它們。

A10 重定向驗證

根據 OWASP,未驗證的重定向和轉發是 Web 應用的第十大嚴重安全問題。它發生在應用接受 URL 或內部頁面作為參數來執行重定向或轉發操作的時候。如果參數沒有正確驗證,攻擊者就能夠濫用它來使其重定向到惡意網站。

這個秘籍中,我們會了解如何驗證我們接受的用于重定向或轉發的參數,我們需要在開發應用的時候實現它。

操作步驟

  1. 不希望存在漏洞嗎?那就不要使用它。無論怎樣,都不要使用重定向和轉發。

  2. 如果需要使用重定向,嘗試不要使用用戶提供的參數(請求變量)來計算出目標。

  3. 如果需要使用參數,實現一個表,將其作為重定向的目錄,使用 ID 代替 URL 作為用戶應該提供的參數。

  4. 始終驗證重定向和轉發操作涉及到的輸入。使用正則表達式或者白名單來檢查提供的值是否有效。

工作原理

重定向和轉發是釣魚者和其它社會工程師最喜歡用的工具,并且有時候我們對目標沒有任何安全控制。所以,即使它不是我們的應用,它的安全問題也會影響我們的信譽。這就是最好不要使用它們的原因。

如果這種重定向的目標是已知站點,例如 Fackbook 或 Google,我們就可以在配置文件或數據表中建立目標目錄,并且不需要使用客戶端提供的參數來實現。

如果我們構建包含所有允許的重定向和轉發 URL 的數據表,每個都帶有 ID,我們可以將 ID 用于參數,而不是目標本身。這是一種白名單的形式,可以防止無效目標的插入。

最后同樣是校驗。我們始終要校驗每個來自客戶端的輸入,這非常重要,因為我們不知道用戶要輸入什么。如果我們校驗了重定向目標的正確性,除了惡意轉發或重定向之外,我們還可以防止可能的 SQL 注入、XSS或者目錄遍歷。所以,它們都是相關的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容