# **OWASP TOP 10 2017** # A1 Injection ## 問題原因 Client端提供的資料並未經過驗證、過濾或清理,使攻擊者可以注入任意語法可能導致機敏資訊外洩。 ## 如何防範 ### 主要 - **使用Prepared Statements(with Parameterized Queries)** - 使用Stored Procedures - 白名單輸入驗證 - Escaping 所有Client端的輸入 ### 加強 - 實施最小權限 - 使用白名單輸入驗證做為輔助防禦 ## 範例 ### **Java** #### unsafe ```java String query = "SELECT account_balance FROM user_data WHERE user_name = " + request.getParameter("customerName"); try { Statement statement = connection.createStatement( ... ); ResultSet results = statement.executeQuery( query ); } ... ``` #### safe ```java // This should REALLY be validated too String custname = request.getParameter("customerName"); // Perform input validation to detect attacks String query = "SELECT account_balance FROM user_data WHERE user_name = ? "; PreparedStatement pstmt = connection.prepareStatement( query ); pstmt.setString( 1, custname); ResultSet results = pstmt.executeQuery( ); ``` # A2 失效的身份認證 (Broken Authentication) ## 問題原因 通常,通過錯誤使用應用程式的身份認證和session管理功能,攻擊者能夠破譯密碼、密鑰、session或token,或者利用其它開發缺陷來暫時性或永久性冒充其他用戶的身份。 ## 如何防範 - 在可能的情況下,實現多因素身份驗證,以防止自動、憑證填充、暴力破解和被盜憑據再利用攻擊。 - 不要使用發送或部署預設的憑證,特別是管理員用戶。 - 執行弱密碼檢查,例如測試新或變更的密碼。 - 將密碼長度、複雜性和循環策略與NIST 800-63 B's guidelines in section 5.1.1 for Memorized Secrets,或其他現代的基於證據的密碼策略相一致。 - 確認註冊、憑據恢復和API路徑,通過對所有輸出結果使用相同的消息,用以抵禦帳戶枚舉攻擊。 - 限制或逐漸延遲失敗的登錄嘗試。記錄所有失敗資訊並在憑據填充、暴力破解或其他攻擊被檢測時提醒管理員。 - 使用伺服器端安全的內置session管理器,在登錄後生成高度複雜的 新隨機session ID。session ID不能在URL中,可以安全地存儲和當登出、閒置、絕對超時後使其失效。 ## 範例 session超時設定不正確。使用者使用公共電腦訪問應用程式。使用者直接關閉瀏覽器分頁就離開,而不是選擇「登出」。攻擊者一小時後使用同一個瀏覽器瀏覽網頁,而當前使用者狀態仍然是經過身份驗證的。 # A3 敏感資料外洩 (Sensitive Data Exposure) ## 問題原因 許多Web應用程式和API都無法正確保護敏感數據,例如:財務數據、醫療數據和PII數據。攻擊者可以通過竊取或修改未加密的數據來實施信用卡詐騙、身份盜竊或其他犯罪行為。未加密的敏感數據容易受到破壞,因此,我們需要對敏感數據加密,這些數據包括:傳輸過程中的數據、存儲的數據以及瀏覽器的交互數據。 ## 如何防範 - 對系統處理、存儲或傳輸的資料分類,並根據分類進行存取控制。 - 熟悉與敏感性資料保護相關的法律和條例,並根據每項法規要求保護敏感性資料。 - 對於沒必要存放的、重要的敏感性資料,應當儘快清除,或者通過PCI DSS標記或攔截。未存儲的資料不能被竊取。 - 確保存儲的所有敏感性資料被加密。 - 確保使用了最新的、強大的標準演算法或密碼、參數、協定和密匙,並且金鑰管理到位。 - 確保傳輸過程中的資料被加密,如:使用TLS。確保資料加密被強制執行,如:使用HTTP嚴格安全傳輸協定(HSTS)。 - 禁止緩存對包含敏感性資料的回應。 - 確保使用密碼專用演算法存儲密碼,如:Argon2、scrypt、bcrypt或者PBKDF2。將工作因素(延遲因素)設置在可接受範圍。 - 單獨驗證每個安全配置項的有效性。 ## 範例 密碼資料庫使用未加鹽的雜湊演算法或弱雜湊演算法去存儲每個人的密碼。一個檔上傳漏洞使駭客能夠獲取密碼檔。所有這些未加鹽雜湊的密碼通過彩虹表暴力破解方式破解。由簡單或快速散列函數生成加鹽的雜湊,也可以通過GPU破解。 # A4 XXE (XML External Entity Injection) ## 問題原因 XXE是針對XML parses的一種攻擊,此攻擊通常發生在使用有弱點的XML parses處理包含對外部實體(external entity)引用的XML輸入。 ## 如何防範 - 可能的話,儘量使用更單純的數據格式如JSON,並避免將機敏資訊反序列化。 - 修補或更新所有XML processors以及libraries。 - 禁用XML External Entity與DTD processing於應用程式的所有XML parsers - 於伺服器端實施白名單輸入驗證、過濾或消毒來防止惡意數據於XML documents、headers、nodes中。 - 驗證XML或XSL文件上傳功能是否使用XSD驗證或類似方法檢查傳入的XML # A5 失效的存取控制 (Broken Access Control) ## 問題原因 未對通過身份驗證的用戶實施恰當的訪問控制。攻擊者可以利用這些缺陷訪問未經授權的功能或數據,例如:訪問其他用戶的帳戶、查看敏感文件、修改其他用戶的數據、更改訪問權限等。 ## 如何防範 存取控制只有在受信任伺服器端程式碼或server-less API中有效,這樣這樣攻擊者才無法修改存取控制檢查或metadata。 - 除公有資源外,預設情況下拒絕訪問。 - 使用一次性的存取控制機制,並在整個應用程式中不斷重用它們,包括最小化CORS使用。 - 建立存取控制模型以強制執行所有權記錄,而不是接受使用者創建、讀取、更新或刪除任何記錄。 - 域存取控制對每個應用程式都是唯一的,但業務限制要求應由域模型強制執行。 - 禁用Web伺服器目錄瀏覽,並確保metadata(如:git)不存在於Web的根目錄中。 - 記錄失敗的存取控制,並在適當時向管理員告警(如:重複失敗)。 - 對API和控制器的訪問進行速率限制,以最大限度地降低自動化攻擊工具的危害。 - 當用戶註銷後,伺服器上的JWT應失效。 開發人員和QA人員應包括功能存取控制單元和集成測試人員。 ## 範例 應用程式在訪問帳號資訊的SQL調用中使用了未經驗證的資料: ``` pstmt.setString(1,request.getParameter("acct")); ResultSet results = pstmt.executeQuery(); ``` 攻擊者只需修改流覽器中的「acct」參數即可發送他們想要的任何帳號資訊。如果沒有正確驗證,攻擊者可以訪問任何用戶的帳戶。 # A6 不安全的組態設定(Security Misconfiguration) ## 問題原因 攻擊者通常會嘗試利用未修補的漏洞或訪問默認帳戶、未使用的頁面、未受保護的文件和目錄等,以獲取未經授權的訪問或取得系統關於系統的資訊。 ## 如何防範 - Development、QA以及production環境應全部使用相同的設定及配置,並在每個環境中使用不同的憑證。 - 在任何平台上避免使用不必要的features、components、documentation及samples。移除或不安裝未使用的功能和框架。 - 檢查和更新所有適合安全配置的記錄、更新及補丁做為補丁程序管理過程的一部份,特別是審視cloud storage的權限。(如: S3 bucket permissions) - 提供有效分段的應用程序體系結構、通過分段,容器化或雲安全組(ACL)在組件或租戶之間提供有效,安全的隔離。 - 提供有效分段的應用程序體系結構、通過分段,確保components或tenants之間的安全隔離,具有各自的segmentation、containerization或cloud的安全群組。 - 確保在所有環境中驗證配置和設置有效性的自動化過程。 # A7 Cross-Site Scripting (XSS) ## 問題原因 Client端提供的數據並未經過驗證、過濾或清理,導致攻擊者能夠任意注入Client端腳本語言(如: javascript)。通常可以搭配信任的網站加上社交工程達成攻擊目的。 ## 如何防範 - HTML Encode - 利用frameworks自動跳脫XSS的設計,例如最新的Ruby on Rails、React JS。了解每個框架的XSS保護的局限性,並適當處理未涵蓋的部份。 - 轉義來自不信任的HTTP request數據。 - 啟用Content Security Policy(CSP)作為針對XSS的深度防禦緩解控制。 # A8 不安全的反序列化(Insecure Deserialization) ## 問題原因 當對不受信任的數據進行操作時,可以將這些本機反序列化機制的功能重新用於惡意影響,已經發現,針對反序列化器的攻擊允許denial-of-service(DoS)、access control和remote code execution(RCE)攻擊。 ## 如何防範 - 在任何序列化object實施完整性檢查(例如: digital signatures),以防止惡意創建object或篡改數據。 - 避免在object創建之前的反序列化過程中強制執行嚴格的類型約束,因為程式設計時通常希望使用一組可定義的class。但已經證明該技術可被繞過,因此不建議僅依靠此技術。 - 可能的話在低特權環境中隔離並運行反序列化的程式。 - log反序列化異常和錯誤。例如: 傳入的類型不是預期的類型,或者反序列化引發異常。 - 限制或監視反序列化的containers或服務器的傳入和傳出網絡連線。 # A9 使用含有已知漏洞的組件 (Using Components with Known Vulnerabilities) ## 問題原因 組件(例如:libraries、frameworks和其他software modules)擁有和應用程式相同的權限。如果應用程式中含有已知漏洞的組件被攻擊者利用,可能會造成嚴重的數據丟失或伺服器接管。同時,使用含有已知漏洞的組件的應用程式和API可能會破壞應用程式防禦、造成各種攻擊並產生嚴重影響。 ## 如何防範 應該制定一個patch管理流程: - 移除不使用的依賴、不需要的功能、元件、檔案和文件。 - 利用如versions、DependencyCheck、retire.js等工具來持續的記錄用戶端和伺服器端以及它們的依賴庫的版本資訊。持續監控如CVE和NVD等是否發佈已使用元件的漏洞資訊,可以使用軟體分析工具來自動完成此功能。訂閱關於使用元件安全性漏洞的警告郵件。 - 僅從官方管道安全的獲取元件,並使用簽名機制來降低組件被篡改或加入惡意漏洞的風險。 - 監控那些不再維護或者不發佈security patches的libraries和元件。如果不能上patch,可以考慮部署虛擬patch來監控、檢測或保護。 每個組織都應該制定相應的計畫,對整個軟體生命週期進行監控、評審、升級或更改配置。 ## 範例 很多時候元件都是以與應用相同的許可權運行的,這使得元件裡的缺陷可能導致各式各樣的問題。這些缺陷可能是偶然的(如:編碼錯誤),也可能是蓄意的(如:組件裡的後門)。下面是一些已被利用的漏洞: - CVE-2017-5638,一個Struts2遠端執行漏洞。可在服務端遠端執行程式碼,並已造成巨大的影響。 # A10 不足的日誌記錄和監控 (Insufficient Logging&Monitoring) ## 問題原因 不足的日誌記錄和監控,以及事件響應缺失或無效的集成,使攻擊者能夠進一步攻擊系統、保持持續性或轉向更多系統,以及篡改、提取或銷毀數據。大多數缺陷研究顯示,缺陷被檢測出的時間超過200天,且通常通過外部檢測方檢測,而不是通過內部流程或監控檢測。 ## 如何防範 根據應用程式存儲或處理的資料的風險: - 確保所有登錄、存取控制失敗、輸入驗證失敗能夠被記錄到日誌中去,並保留足夠的使用者上下文資訊,以識別可疑或惡意帳戶,並為後期取證預留足夠時間。 - 確保日誌以一種能被集中日誌管理解決方案使用的形式生成。 - 確保高額交易有完整性控制的審計資訊,以防止篡改或刪除,例如審計資訊保存在只能進行記錄增加的資料庫表中。 - 建立有效的監控和告警機制,使可疑活動在可接受的時間內被發現和應對。 - 建立或採取一個應急回應機制和恢復計畫,例如:NIST 800-61 rev 2或更新版本。 目前已有商業的和開源的應用程式防護框架(例如:OWASP AppSensor)、Web應用防火牆(例如:Modsecurity with the OWASP Core Rule Set)、帶有自訂儀錶盤和告警功能的日誌關聯軟體。 ## 範例 攻擊者使用通用密碼進行使用者掃描並能獲取所有使用此密碼的帳戶。對於其他帳戶而言,將僅有一次失敗的登錄嘗試記錄。一段時間以後,攻擊者可以用另一個密碼再次進行此活動。