歡迎光臨
每天分享高質量文章

Java 應用程式漏洞:概念及如何修複

來自:唐尤華

譯自:https://dzone.com/refcardz/java-application-vulnerabilities

與其他任何應用程式一樣,Java 應用程式也存在安全漏洞。 本文重點介紹了可能影響 Java 應用程式前幾名的漏洞以及如何消除這些漏洞。

1. 引言

 

過去15年中開發得企業應用程式有一半是用 Java 編寫的,這使得它們在企業中幾乎無處不在。不幸的是,這意味著 Java 應用程式也是駭客最常攻擊的標的之一。

 

對於一般漏洞和一些 Java 平臺特有漏洞,Java 的防範都很薄弱。 例如,一般型別的漏洞包括:

 

  • 標準庫中的漏洞
  • 程式設計錯誤造成的漏洞(比如查詢結構不當)

 

Java 平臺特有漏洞包括:

 

  • Java 庫中的漏洞
  • Java 沙盒機制中的漏洞,攻擊者會利用它們繞過安全管理器設定的限制

 

開發安全的 Java 應用程式,免受上述漏洞的影響,是確保應用程式健壯並免受安全威脅的最佳方法。 將安全性納入開發工作流程有助於開發人員避免產生漏洞,在開發過程中糾正潛在的漏洞,在時間和資源上都比在生產環境中發現漏洞成本低得多。

本文旨在幫助開發人員理解常見的 Java 漏洞,以及如何在開發過程早期修複它們。

 

2. 最大的 Java 漏洞

 

下麵是最常見、最普遍、最重要的 Java 漏洞。 這份串列根據2017年白帽安全應用程式安全統計報告編譯而成,記錄了 Java 應用程式中發現的漏洞。 介紹了每種漏洞型別、發生的方式和位置、如何修複漏洞實體,以及關於該漏洞的其他一般資訊。

 

獲勝者是……

 

在軟體開發過程中,靜態應用程式安全測試(SAST)中最常見的程式碼漏洞是 未打補丁的開發庫(Unpatched Libraries)。為什麼?因為現代軟體大部分是由單獨的元件組合而成的,而且現在每個人都使用開源庫。 這些庫提供了現成的選項,但不是很安全。

 

同樣的情況適用於第二種常見錯誤:錯誤的應用程式配置。許多軟體元件(比如嵌入式除錯和 QA 功能)對安全性幾乎沒有考慮,開發人員會預設啟用這些配置。這樣為供攻擊者提供了可利用的配置漏洞。這些啟用的功能會被用來繞過身份驗證,進而獲得訪問敏感資訊的許可權,甚至有可能讓攻擊者用來提升更高的特權。

 

解決辦法?軟體組成分析(SCA)對於保護第三方或開放原始碼程式碼至關重要。 SCA 深入研究了專有、開放原始碼和商業程式的原始碼,進而識別和列出所有存在的漏洞。

關鍵的軟體錯誤(比如 SQL 註入)必須在開發過程中修複,減少在生產環境中發生漏洞。

 

 

3. 未打補丁的開發庫

 

關鍵風險:OWASP A9:統計報告排名1

 

描述

未打補丁的開發庫會給應用程式帶來嚴重的風險。使用這樣的開發庫可能會引入漏洞,繞過現有的安全管控。攻擊者可以利用一些眾所周知的資訊來源,比如國家漏洞資料庫(National Vulnerability Database)、 US-CERT、 CVE 資料庫等,來識別這些潛在的漏洞,並利用它們帶來威脅。

 

解決方案

確保元件及時更新並打好補丁。監控上報的漏洞,以便及時採取行動。使用依賴項管理器(例如 Maven  部分),為多次宣告或有依賴傳遞的庫定義最小依賴版本。防止系統和服務洩漏不必要的資訊,如版本資訊。如果由於某種原因,不能被修補或替換某個易受攻擊的開發庫,請確保應對措施已經到位,例如正確配置網路防火牆、IDS/IPS 或應用層防火牆。

 

在選擇元件之前,對已知的漏洞進行研究,並將調查結果儲存到中央倉庫,包括已知的易受攻擊的庫串列。確保所有開發團隊都能訪問這些資訊,以便可以立即處理易受攻擊的開發庫,從而減少不小心用到這些元件的可能性。一定要考慮任何已識別的漏洞的實際影響。在某些情況下,風險可能遠遠高於正常情況;而在其他時候,脆弱性可能與元件的使用方式無關。

 

建立一個公司層面的治理策略,用來選擇、測試和批准開發團隊使用的元件。當元件批准使用後,將它們存到中央倉庫,並與組織中的其他開發團隊共享。對同一個問題,最好只有一個解決方案,而不是多個解決方案。為了進一步提高一致性和安全性保證,應該在整個組織內保持使用相同的版本和補丁級別。

 

  • 依賴管理工具(例如 Maven)
  • WhiteHat Sentinel Source 提供了相關開發庫和框架的資訊

 

其他資源

Maven 依賴管理

OWASP 排名前10的漏洞

 

4. 應用程式配置不當:Servlet 洩漏

 

關鍵風險:OWASP A5:統計報告排名2

 

描述

Axis 應用程式部署時配置了管理介面,此介面可以在不使用正常的身份驗證/訪問限制的情況下檢視。惡意使用者透過此介面能訪問意料之外的伺服器功能。如果應用程式“僅限內部”使用,那麼針對內部網路訪問需求的限制可能會減少。 然而,將未經身份驗證的管理功能暴露給內部網路仍是不安全的,應被視為具有一定的洩漏風險。

 

解決方案

從生產環境 web.xml 中刪除突出有明顯含義的程式碼片段。 因為 AdminServlet 和 SOAPMonitorService 都不支援身份驗證,所以禁用這些 servlet 是唯一的安全選項。

 

其他資源

Apache Axis:Web 服務安全指南

5. 應用程式配置不當:許可權過多

 

低風險:OWASP A5:統計報告排名2

 

描述

應用程式可以使用自定義許可權,允許單獨的應用程式透過 API 訪問硬體層功能。這些獨立的應用程式可以透過 API 繞過正常的提示過程訪問敏感功能。

 

解決方案

應用程式應該只請求功能所需的最小許可權,不要請求任何不必要的許可權,不要請求任何未使用的許可權。應用程式將來應該提示使用者撤消不需要的許可權。

6. 應用程式配置不當:禁用全域性錯誤處理

中等風險:OWASP A5:統計報告排名2

 

描述

禁用全域性錯誤處理機制會增加風險,攻擊者透過堆疊跟蹤資訊會瞭解更加詳細實現細節。

 

解決方案

為了讓錯誤訊息洩露實現細節的風險降到最低,應確保應用程式部署時宣告一個錯誤頁面,用以捕獲應用程式丟擲的所有未捕獲的異常。

 

示例

web.xml 應當定義錯誤處理:

 

<error-page>
<error-code>500error-code>

<location>/path/to/default_500.jsplocation>
error-page>
<error-page>
<exception-type>java.io.IOExceptionexception-type>
<location>/path/to/default_exception_handler.jsplocation>
error-page>

7. 跨站指令碼(XSS)

 

高風險:OWASP A3:統計報告排名3

 

描述

跨網站指令碼漏洞指,攻擊者在表單或查詢變數中嵌入惡意客戶端指令碼或 HTML 並透過 web 介面提交給網站,惡意內容被髮送給終端使用者。持久化/跨網站指令碼攻擊指,惡意內容是由一個使用者(攻擊者)提交並儲存在資料庫中,然後傳送給另一個使用者(受害者)。反射跨網站指令碼攻擊指,攻擊者誘使受害者透過電子郵件或攻擊者控制的網站上的連結提交汙染後的資料。

 

擊者可以使用 XSS 向不知情的使用者傳送惡意指令碼或其他內容。 終端使用者和他們的瀏覽器都不知道這些內容實際上不是由受信任的網站生成的。惡意指令碼可以訪問瀏覽器中的任何 Cookie、會話令牌或其他敏感資訊。這些指令碼甚至可以重寫 HTML 頁面的內容,造成網路釣魚攻擊、身份盜竊、網站破壞、拒絕服務和其他攻擊。

 

解決方案

阻止大多數 XSS 攻擊的最可靠的方法是,對所有來源的資料使用 HTML 或 URL 編碼後輸出資料。這樣可以確保受汙染的資料不會影響任何來源的輸出,包括使用者輸入、其他應用程式共享的資訊、來自第三方的資訊。對所有輸出資料統一編碼讓應用程式更容易審計,無需執行耗時(且昂貴)的資料流分析。需要註意的是,編碼功能必須能夠處理不同的背景關係輸出,包括 HTML、HTML 屬性、URL、CSS 和 JavaScript。單一編碼方法未必能在每種背景關係中減輕 XSS 攻擊帶來的影響。

 

如果對輸出編碼不可行,另一個最有效的方法是根據允許的字元白名單仔細過濾所有輸入資料。這種方法的優點是可以在外部執行,無需修改應用程式原始碼。對第三方檢索資料、其他應用程式共享的資料應與使用者輸入資料一起過濾。白名單應該只包括可能是使用者輸入的合法字元。下列字元對於進行 XSS 攻擊特別有用,在任何編碼或過濾方案中都應該考慮:< > “ ‘ ; & ?。應用程式可能需要這些字元中的一個或多個,例如單引號。如果作為輸入過濾方案的一部分無法刪除一個或多個危險字元,則必須小心地處理這些字元。例如,可以對輸入進行編碼,並將這些字元儲存在資料庫中。理想情況下,應用程式應該謹慎地執行輸入驗證,並使用輸出編碼來防範 XSS 和其他註入攻擊。

 

其他資源

  • 跨網站指令碼缺陷
  • 預防跨網站指令碼指南

 

8. 密碼學:使用不恰當的偽隨機數發生器

 

中等風險:OWASP NA:統計報告排名4

 

描述

需要隨機結果,而軟體生成可預測的值,這時就會產生隨機性不足。當安全機制依賴於隨機且不可預測的值來限制對敏感資源訪問時,比如初始向量(IV)、生成金鑰或會話 ID 的種子,那麼使用隨機性不足的數字可能會讓攻擊者有機可乘,會透過猜測值來訪問該資源。

 

使用隨機性不夠充分的隨機數,潛在後果是資料被盜竊或修改,帳戶或系統受到損害,最終名譽掃地。

 

解決方案

在安全背景關係中使用隨機數時,請使用加密的安全偽隨機數生成器(CSPRNG)。

 

示例

byte[] randomBytes = new byte[8];
SecureRandom random = new SecureRandom();
random.nextBytes(randomBytes);

9. 應用程式配置不當:除錯

 

中等風險:OWASP A5:統計報告排名5

 

描述

應用程式錯誤通常發生在正常操作中,特別是當應用程式被誤用時,甚至是無意中發生了錯誤。如果開啟除錯,那麼在除錯時,應用程式可能會向終端使用者提供不該被訪問內部資訊,而且可能會被用來攻擊應用程式。終端使用者看到的錯誤資訊可能包括伺服器資訊、詳細的異常訊息、堆疊跟蹤,甚至發生錯誤的頁面程式碼。這些資訊可以被用來制定攻擊計劃。

 

如果應用程式提供了生產環境中的除錯樣式啟用開關,攻擊者可能會猜到或瞭解這個引數,並利用應用程式可能提供的各種附加資訊,甚至自定義除錯樣式實現繞過身份驗證獲得為測試分配管理員級許可權。

 

解決方案

生產環境中應禁用除錯樣式。除了程式語言本身提供的任何除錯樣式外,開發人員還可以自定義除錯樣式。自定義除錯選項應該儲存在應用程式配置檔案中而不是原始碼中,但是可能需要搜尋程式碼庫以驗證沒有隱藏的除錯選項。

 

生產程式碼通常不能進入除錯樣式或生成除錯訊息。但如果需要此功能,則應透過編輯伺服器上的檔案或配置選項來啟用除錯樣式。特別註意,除錯樣式不應該由應用程式本身中的選項啟用。例如,不應該傳入 URL 引數來觸發除錯樣式,例如:https://www.website.com?debug=true。無論引數多麼模糊,它從來都不是一個安全的選項。

 

應用程式使用的框架和元件也可以有自己的除錯選項。在部署應用程式之前,必須在整個應用程式中禁用除錯選項。

 

示例

Java 應用程式中可能存在許多除錯樣式的實體,根據容器的型別各有不同。下麵是一個禁用 JSP Servlet 除錯樣式的示例:

 

<servlet>
<servlet-name>jspservlet-name>

<servlet-class>oracle.jsp.runtimev2.JspServletservlet-class>
<init-param>
<param-name>debug_modeparam-name>
<param-value>falseparam-value>
init-param>

由於開發人員可能已經實現了自定義除錯樣式,所以一定要檢查配置檔案,併在程式碼庫中搜索以下內容:

DEBUG MODE
debug = true
debug = 1
debug

10. 洩漏:明文密碼

 

中等風險:OWASP A2:統計報告排名6

 

描述

如果應用程式在原始碼中包含一個或多個硬編碼的密碼,那麼攻擊者可以從原始碼或編譯的二進位制檔案中提取憑據,並試圖訪問相應的服務。使用像 Base-64 這樣的加密演演算法是不夠的。

 

採用明文儲存密碼(例如在應用程式的屬性或配置檔案中)可能會導致帳戶或系統受到損壞。這會把密碼暴露給任何可以訪問應用程式配置檔案的人,包括開發人員、架構師、測試人員、審計人員和開發經理。由於其他人有可能接觸使用者密碼,所以不能假定帳戶的所有者是唯一能夠登入該帳戶的人。

 

解決方案

只要有可能,系統密碼或者含有密碼的配置檔案應該加密。

 

應該用金鑰對憑證加密,並且儲存到磁碟上的一個網路無法訪問的目錄。執行的 web 應用程式(webserver)的使用者對該目錄只具備只讀許可權。金鑰與憑據採取相同的方式處理。隨後,應用程式可以(從已知的固定目錄)讀取金鑰、讀取加密憑據、解密、使用。每隔30至90天加密金鑰應該輪換一次。

 

使用者密碼應該使用強大的單向雜湊演演算法(如 SHA-256)來儲存。在對每個密碼進行雜湊前應該加鹽。鹽的長度至少應該是64位,並且對每個使用者是隨機且唯一。

 

譯註:鹽(Salt),在密碼學中,是指透過在密碼任意固定位置插入特定的字串,讓雜湊後的結果和使用原始密碼的雜湊結果不相符,這種過程稱之為“加鹽”。

 

示例

在 Java 中,有許多可用於加密/解密資料的方法和庫。許多常見的方法都不夠安全。Java 開發人員通常用 Base-64 或 DES 對密碼加密——這兩種方法都不夠安全,尤其是編碼。

 

下麵的程式碼使用安全演演算法 AES 來加密解密:

 

public static String encrypt(String value, File keyFile)
throws GeneralSecurityException, IOException
{
if (!keyFile.exists()) {
KeyGenerator keyGen = KeyGenerator.getInstance(CryptoUtils.AES);
keyGen.init(128);
SecretKey sk = keyGen.generateKey();
FileWriter fw = new FileWriter(keyFile);
fw.write(byteArrayToHexString(sk.getEncoded()));
fw.flush();
fw.close();
}
SecretKeySpec sks = getSecretKeySpec(keyFile);
Cipher cipher = Cipher.getInstance(CryptoUtils.AES);
cipher.init(Cipher.ENCRYPT_MODE, sks, cipher.getParameters());
byte[] encrypted = cipher.doFinal(value.getBytes());
return byteArrayToHexString(encrypted);
}

11. 註入:未知的直譯器

 

中等風險:OWASP A5:統計報告排名7

 

描述

應用程式在建立和使用直譯器的同時也使用了非可信的資料。攻擊者獲取非可信資料,並將其作為引數傳遞給直譯器進行危險呼叫。由於無法正確驗證或對直譯器使用的資料進行編碼,從而增加了註入攻擊風險。這種註入通常讓攻擊者得以在程式處理直譯器結果時能夠執行任意程式碼。

 

解決方案

定義一組嚴格的標準,應用程式應接受哪些作為有效輸入,併在執行前對傳遞給直譯器的所有非可信資料根據背景關係進行編碼。

 

12. 拒絕服務攻擊(Dos):Readline

 

中等風險:OWASP NA:統計報告排名7

 

描述

java.io.BufferedReader readLine() 方法用於從套接字或檔案讀取資料;但是,readLine() 會一直讀取資料,直到遇到換行符或回車。如果找不到這兩個字元,readLine() 將無限地讀取資料。如果攻擊者對正在讀取的原始碼有任何控制,他或她可以註入不帶有這些字元的資料,從而在系統中製造拒絕服務攻擊。即使讀取的行數有限,攻擊者也可以傳入沒有換行字元的大檔案,並導致 OutOfMemoryError 異常。

 

解決方案

OWASP 的企業安全 API 為 readLine() 提供了一個更安全的替代方案,稱為 SafeReadLine()。 此方法從輸入流讀取資料,直到達到行尾或字元數的最大值,從而有效降低了這種風險。

 

另一個解決方案是重寫 BufferedReader 和 readLine() 方法,並對可讀取的最大字元數進行限制。在缺乏更安全方法的情況下,盡可能避免接收客戶端的輸入,並確保讀取的資料是可信的。

 

示例

可以使用 OWASP ESAPI 的 safeReadLine() 安全地讀取非可信資料,像下麵這樣:

 

ByteArrayInputStream s = new ByteArrayInputStream("testinput".getBytes());
IValidator instance = ESAPI.validator();
try {
String u = instance.safeReadLine(s, 20);
} catch (ValidationException e) {
// Handle exception
}

13. 濫用 URL 重定向

 

中等風險:OWASP A10:統計報告排名9

 

描述

應用程式經常使用儲存的 URL 把使用者重定向到其他頁面。有時候,標的頁面由非可信引數指定,這讓攻擊者得以選擇標的頁面或地址。這樣的重定向可能不恰當地利用了使用者對受攻擊網站的信任。

 

解決方案

如果非可信資料成為重定向 URL 的一部分,請確保提供的資料經過了適當的驗證,且來自合法的、經過授權的使用者請求。建議重定向目的地由伺服器端“目的地 id”驅動,而不是由使用者請求中的 URL 決定。查詢對映表或訪問控製表最適合達成這個標的。

 

14. 會話超時設定過短

 

中等風險:OWASP A2:統計報告排名10

 

描述

PCI 資料安全標準 V3,8.1.8節規定了,應用程式關鍵元件的會話超時最長15分鐘:“如果會話空閑時間超過15分鐘,需要使用者重新驗證以重新啟用終端或會話”。

會話超時設定過長或者無超時設定可能幫助攻擊者實施重播攻擊或劫持會話,社會工程學攻擊得手的成功率也更高。如果使用者沒有關閉應用程式,攻擊者有更大的機會控制使用者的計算機。

 

如果沒有在 web 應用程式配置中指定會話超時,那麼將使用預設值,通常是24分鐘、30分鐘或60分鐘,這取決於 web 伺服器、版本及其配置。

 

解決方案

一般來說,使用者會話超時的空閑時間應在15-20分鐘以內,對敏感應用程式,超時時間應小於15-20分鐘。如果有配置選項,請考慮禁用“滑動過期”。確有必要啟用此選項,請考慮在滑動超時之外實現強制會話超時。會話超時後,應用程式應該設定會話無效、刪除會話資料以及所有 Cookie 和身份驗證令牌。

 

示例

可以在伺服器預設 web.xml 中配置會話超時,也可以為每個 web 應用程式單獨配置。 下麵的程式碼應該包含在應用程式的 web.xml 檔案中:

 

<session-config>
<session-timeout>15session-timeout>

session-config>

如果使用了 WebLogic,還需要在 WebLogic.xml 檔案中指定會話超時。下麵的程式碼將超時設定為15分鐘:

xml version="1.0" encoding="ISO-8859-1"?>
<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90">
<session-descriptor>
<timeout-secs>900timeout-secs>
session-descriptor>

weblogic-web-app>

15. 訪問策略缺失

 

高風險:OWASP A5:統計報告排名13

 

描述

應用程式沒有為一個或多個元件使用訪問控制策略。訪問控制缺失可能導致敏感功能暴露給不相關的使用者。惡意使用者會尋找這種功能,從而對其他使用者或應用程式本身造成傷害。

 

在 Websphere 中,如果啟用透過類名 Servlet,那麼和 Android 允許透過類名呼叫類似。 假設存在下麵這樣的配置或者沒有宣告變數,則允許呼叫 Servlet 無需任何許可權:

 

enable-serving-servlets-by-class-name value="true"

解決方案

對應用程式中可能存在的所有敏感功能元件使用訪問控制策略。透過新增下麵配置,防止 Servlet 按 classname 提供服務:

enable-serving-servlets-by-class-name value="false"

16. 傳輸層保護不足

描述

需要保護敏感資料傳輸時,應用程式通常無法對網路通訊加密。因此,必須對所有認證連線進行加密(通常是 TLS),特別是 Internet 訪問的網頁。後端連線也應當加密。否則應用程式會向與應用程式主機位於同一網路中的惡意攻擊者洩漏身份驗證或會話令牌。雖然比起外部網際網路,後端連線被利用的可能性更低。然而,一旦被攻擊造成的使用者帳戶洩露會更嚴重。

 

傳輸敏感資料(如信用卡或健康資訊)時,無論何時都應當加密。攻擊者可能會濫用回到純文字處理或因為其他原因被迫退出加密樣式的應用程式。

 

解決方案

確保應用程式具備安全約束,該約束定義了基於機密性和完整性的安全傳輸保證,確保所有資料在傳輸過程中不被偷窺或更改。如果必須在負載均衡器、 web 應用防火牆或其他內網主機上終止 TLS 傳輸,應該對傳輸到標的主機的資料重新加密。

17. 總結

 

所有組織都必須在他們的 SDLC 中更早地實現應用程式安全性程式。事實證明,發現和修複缺陷越早越好,而且成本也更低。開發過程中的常規安全測試讓開發出的應用程式功能更強大。將多種測試方案(如 DAST、SAST、mobile 等)直接整合到 SDLC 中的組織可以獲得最好的效果。當今的應用程式安全平臺透過軟體組成分析、API 測試、培訓和其他服務進一步擴充套件了可見性和可控性。

 

從 WannaCry 到9月份的 Equifax 攻擊,我們幾乎每天都被提醒,不解決應用程式中的漏洞可能導致可怕的攻擊,然而這些攻擊是可以避免的。在數字商業時代,採用安全的 DevOps 或 DevSecOps 對於確保真正的安全是非常必要的。

贊(0)

分享創造快樂