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

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)

分享創造快樂