程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> WebSphere >> WebSphere Application Server V7、V8和V8.5中的高級安全性加強 二

WebSphere Application Server V7、V8和V8.5中的高級安全性加強 二

編輯:WebSphere

高級安全注意事項

簡介

第 1 部分 解釋了 IBM WebSphere Application Server V7.0 和更高版本在設計時如何考慮到默認安全性安全原則。目標是在最常見的配置和比較簡單的環境中,讓這個產品在默認情況下具有合理的安全水平(盡管這個目標還沒有完美地實現)。前一篇文章最後介紹了 WebSphere Application Server 中已經采用的許多重要的基於基礎架構的預防性安全措施。本文將介紹基於應用程序的其他預防性措施,然後討論一些重要的注意事項。

盡管本文中的信息基於 IBM WebSphere Application Server V7、V8.0 和 V8.5,但是討論的大多數問題同樣適用於 V6.1。對於某個版本特有的問題,我們會專門指出。如果您使用以前的 WebSphere Application Server 版本,請參考 早期文章,因為具有顯著的版本差異,這些差異進而會導致文章之間的差異。
配置文件備注

如果熟悉 V8.5 之前的 WebSphere Application Server,您就會知道必須要創建一個或多個配置文件。該配置文件可能是一個 Application Server(或 Base)配置文件、一個 Deployment Manager 配置文件等。在本文的剩余部分中,這些配置文件被稱為 “完整” 配置文件。進行這樣的區分是為了將這些配置文件與 V8.5 中新增的配置文件(Liberty 配置文件)進行對比。本文還提供了特定於新的 Liberty 配置文件的一些建議。

基於應用程序的預防性措施
配置措施

到目前為止,本文的重點是介紹創建安全的 IBM WebSphere Application Server 基礎架構可以采取的基本步驟。這顯然很重要,但只關注基礎架構是不夠的。既然基礎架構已經加強了,那麼現在有必要研究一下應用程序需要做哪些事情來確保安全性。當然,應用程序必須利用 WebSphere Application Server 提供的基礎架構,但應用程序開發人員還必須執行(或避免)其他一些操作來盡可能地提高應用程序的安全性。

不要將 Web 服務器的文檔根設置為 WAR

仔細檢查每個 servlet 別名是否安全

不要通過類名提供 servlet

不要將敏感信息放在 WAR 根目錄中

定義默認的錯誤處理程序

考慮禁用文件服務和目錄浏覽

啟用會話安全性

注意定制的 JMX 網絡訪問

為了幫助您將這些措施與特定的攻擊類別聯系起來,每個措施都使用了 第 1 部分 介紹的標記來表示攻擊的類別。

1. 不要將 Web 服務器的文檔根設置為 WAR

易受攻擊來源:外部

WAR 文件包含應用程序代碼和大量敏感信息。其中只有一部分信息可以向 Web 提供的內容。因此,將 Web 服務器文檔根設置為 WAR 根目錄是不合適的。如果這樣做,Web 服務器會不加解釋地提供 WAR 文件的所有內容。這會導致將代碼、未經處理的 JSP 和其他內容提供給最終用戶。(這項措施只在 Web 服務器和應用程序服務器放在一起時才有用,如果您遵循 第 1 部分 中給出的指南,通常不會出現此情況。)

2. 仔細檢查每個 servlet 別名是否安全

易受攻擊來源:外部

WebSphere Application Server 通過 URL 保護 servlet。每個要保護的 URL 都必須在描述應用程序的 web.xml 文件中指定。如果 servlet 不止有一個別名(也就是說,多個 URL 訪問相同的 servlet 類),或者有許多 servlet,那麼很容易遺忘對某個別名的保護。需要謹慎處理這一點。由於 WebSphere Application Server 保護的是 URL,而不是底層類,所以即使只有一個 servlet URL 是不安全的,入侵者也能夠繞過您的安全措施。為了減少這種威脅,應該盡可能地使用通配符來保護 servlet。如果那樣做不合適,則應該在部署前再次仔細檢查 web.xml 文件。

APAR PK83258(在 WebSphere Application Server Versions 7.0.0.7 和 6.1.0.27 中)會像對待 GET 請求那樣檢查 HEAD 請求的授權,從而在一定程度上堵住了這個漏洞。

在為 servlet 指定授權約束時,要確保不列出任何方法,或者非常仔細地列出 servlet 的所有方法(很可能在多個約束中),比如 GET、POST、PUT、HEAD 等。對於每個 Java EE 規范,如果授權約束顯式地列出方法,沒有提到的方法就沒有授權約束!這對於 HEAD 等方法尤為危險,HEAD 在默認情況下通過調用 GET 獲取所需的標頭,這實際上會調用 GET 方法,但不會檢查它的授權約束。清單 1 中的 web.xml 代碼是不安全的,而清單 2 中的代碼是安全的。

清單 1. web.xml – 不安全
<security-constraint>
        <web-resource-collection>
            <web-resource-name>myservlet</web-resource-name>
            <url-pattern>/myservlet</url-pattern>
            <http-method>GET</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>arole</role-name>
        </auth-constraint>
</security-constraint>

清單 2. web.xml – 安全

<security-constraint>
    <web-resource-collection>
        <web-resource-name>myservlet</web-resource-name>
        <url-pattern>/myservlet</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>arole</role-name>
    </auth-constraint>
</security-constraint>

下面的方法可從每個 web.xml 中獲取,以確保權限是受限的:

定義一個初步安全約束,比如清單 3 中所示的約束。這表明所有 URL(除非被更具體的模式覆蓋)僅限於 NoAccess 角色。NoAccess 角色名稱可預先綁定到 None 特殊角色。

       清單 3

<security-constraint>
    <web-resource-collection>
        <web-resource-name>DefaultDeny</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>NoAccess</role-name>
    </auth-constraint>
</security-constraint>

如果使用基於表單的登錄,則應定義寬松的約束,允許 Web 容器向任何用戶顯示登錄頁面(和必要的圖形等),甚至未經過身份驗證的用戶也能看到這些(清單 4)。AllUsers 角色名稱可預先綁定到 Everyone 特殊角色。
清單 4

<security-constraint>
    <web-resource-collection>
        <web-resource-name>LoginForm</web-resource-name>
        <url-pattern>/Login.jsp</url-pattern>
        <url-pattern>/images/*.gif</url-pattern>
        <url-pattern>/css/*.css</url-pattern>
        <http-method>GET</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>AllUsers</role-name>
    </auth-constraint>
</security-constraint>

查看本欄目

添加上述兩個 “默認” 約束後,需要為每個添加到應用程序中的適合該 URI 的 servlet 添加 “真正的” 安全約束元素。

此方法的優勢是,添加到 Web 應用程序的新端點默認無法訪問。如果添加了新的 servlet,則必須為這個新的 URL 添加一個安全約束,以便任何人都可以使用它。使用 “默認拒絕” 設計是開發安全應用程序的基礎。

如果使用 Java 注釋定義安全性約束,那麼您可以利用 ServletSecurity.EmptyRoleSemantic.DENY 約束。例如,/simple URL 允許使用針對 AnyUser 角色的 POST 和 GET 方法,但剩余方法會遭到拒絕(清單 5)。
清單 5. 使用注釋為 HTTP 方法提供安全的默認設置的示例

@WebServlet(description = "Returns msg and user info", urlPatterns = { "/simple*"})
@ServletSecurity(
    value = @HttpConstraint(ServletSecurity.EmptyRoleSemantic.DENY),
    httpMethodConstraints = 
       {@HttpMethodConstraint(value = "GET",  rolesAllowed = "AnyUser"),
         @HttpMethodConstraint(value = "POST", rolesAllowed = "AnyUser")})
publicclassSimple extendsHttpServlet {
…

依據 Java                Servlet Specification 3.0(2009 年 12 月)第 13.4.1 條,HttpConstraint(ServletSecurity.EmptyRoleSemantic.DENY) 的 value 屬性具有以下效果:

“HttpConstraint 定義要應用到所有未在 httpMethodConstraints 返回的數組中表示的 HTTP 方法的保護措施。”

3.  不要通過類名提供 servlet

易受攻擊來源:外部

可以通過類名或一般的 URL 別名來提供 servlet。通常應用程序會選擇後者。也就是說,開發人員在 web.xml 文件中手動定義從每個 URL 到每個 servlet 類的准確映射,或者使用各種 WebSphere Application Server 開發工具來定義該映射。

然而,WebSphere Application Server 也允許通過類名提供 servlet。通用的 URL(例如 /servlet)並沒有為每個 servlet 定義映射,而是提供所有 servlet。假設基本路徑後面的路徑成分是 servlet 的類名。例如,"/servlet/com.ibm.sample.MyServlet" 引用 servlet 類 "com.ibm.sample.MyServlet"。

通過類名提供 servlet 是通過在 ibm-web-ext.xmi 文件中將 serveServletsByClassnameEnabled 屬性設置為 true 完成的,或者在 IBM Rational Application Developer 的 WAR 編輯器中選中 servlets by classname。請不要啟用這個特性,Rational Application Developer 在默認情況下已經啟用它,所以如果您正在使用 Rational Application Developer,那麼您必須顯式禁用它(圖 1)。

圖 1. 不要通過類名提供 servlet

圖 1. 不要通過類名提供 servlet

這個特性使得知道 servlet 類名的任何人都可以直接調用它。即使 servlet URL 是受保護的,攻擊者也能繞過正常的基於 URL 的安全措施。另外,根據類裝載器的結構,攻擊者可能能夠調用您的 Web 應用程序之外的 servlet,比如 IBM 提供的 servlet。(請注意,此處 沒有將示例應用程序安裝在生產環境中作為第一步,以預防出現這種情況。)

作為管理員,您可能不確定各個應用程序的設置是否錯誤地通過類名提供了 servlet。您可以 通過在 JVM 上設置一個定制屬性 com.ibm.ws.webcontainer.disallowAllFileServing,將應用服務器配置為忽略應用程序中的這個屬性,從而禁止通過類名提供 servlet。Liberty 配置文件的等效結構已在清單 6 中給出。

清單 6

<webcontainer disallowAllFileServing=”true” />

4. 不要將敏感信息放在 WAR 根目錄中

易受攻擊來源:外部

WAR 文件包含可提供的內容。Web 容器將提供 WAR 文件根目錄中的任何文件。只要僅在根目錄中放置應該提供的內容,就不會出現問題。因此,決不要將不應該顯示給最終用戶的內容放在 WAR 的根目錄中。例如,不要將屬性文件、類文件或其他重要信息放在根目錄中。如果您必須將這種信息放在 WAR 中,則應將其放在 WEB-INF 目錄中,這是 servlet 規范所允許的。Web 容器決不會提供那裡的信息。

5. 定義默認的錯誤處理程序

易受攻擊來源:外部

當 Web 應用程序中出現錯誤時,即使是在應用程序分派之前(例如 WebSphere Application Server 無法發現目標 servlet),也會向用戶顯示錯誤消息。在默認情況下,WebSphere Application Server 會顯示錯誤的原始異常堆棧轉儲。這不僅對最終用戶非常不友好,還會暴露應用程序的相關信息(堆棧信息中有類和方法的名稱)。同時還顯示異常消息,其中可能包含敏感信息。

最好定義默認的錯誤頁面,每當出現未處理的異常時就顯示它,從而確保最終用戶永遠看不到原始錯誤消息。此頁面可以是對用戶友好的錯誤消息,但不是堆棧跟蹤。默認的錯誤頁面是在 ibm-web-ext.xmi 中使用 defaultErrorPage 屬性定義的,也可以在 Rational Application Developer 中使用 Web 部署描述符編輯器(Extensions 選項卡)進行設置。

圖 2. 定義默認的錯誤頁面

圖 2. 定義默認的錯誤頁面

查看本欄目

6. 考慮禁用文件服務和目錄浏覽

易受攻擊來源:外部

可以通過禁用 Web 應用程序中的文件服務和目錄浏覽,進一步限制提供不適當內容的風險。

圖 3. 禁用文件服務和目錄浏覽

圖 3. 禁用文件服務和目錄浏覽

當然,如果 WAR 包含可提供的靜態內容,則必須啟用文件服務。很少存在需要啟用目錄浏覽的原因。

7. 啟用會話安全性(僅適用於 V7.0)

易受攻擊來源:網絡、外部

不同於 WebSphere Application Server V8.0(和更高版本),WebSphere Application Server V7.0 通常並不強制對 HTTP 會話訪問進行任何授權。因此,任何具有有效會話標識符的請求都可以訪問會話。雖然會話標識符是不可猜測的,但也可能通過其他手段獲得會話標識符。結果,從更低的 WebSphere Application Server 版本遷移的、未啟用會話安全性的用戶的應用程序可能被破壞。請注意,這也是 Liberty 配置文件的默認行為。

要想降低這種攻擊形式的風險,應該考慮啟用會話安全性。這一設置是在 Application server > <server name> > Web container > Session management 面板中配置的。只需選擇 Security integration 選項即可,如圖 4 所示。

圖 4. 會話安全性集成

圖 4. 會話安全性集成

WebSphere Application Server 將跟蹤哪個用戶(根據用戶提供的 LTPA 憑證來確定)擁有哪個會話,確保只有針對該用戶的請求才能訪問該會話。

在極少數情況下,這種設置會破壞 Web 應用程序。如果應用程序同時包含安全的(具有授權約束)和不安全的 servlet,那麼不安全的 servlet 將無法訪問會話對象。一旦某個安全的 servlet 訪問啟用了該會話,它會被標記為歸該用戶 “所擁有”。如果以匿名方式運行的不安全的 servlet 試圖訪問這些頁面,就會遭遇授權失敗。從 WebSphere Application Server V6.1 開始,可以更改授權行為,確保沒有授權約束的 servlet 能夠繼承當前用戶身份(如果已經有的話),這樣就解決了這個問題。圖 5 說明如何設置這個特性。

圖 5. 保留現有的身份

圖 5. 保留現有的身份

在 WebSphere Application Server V8.0 中,服務器默認設置進行了兩方面的更改。將啟用會話安全性集成與 “在訪問不受保護的 URI 時使用可用的身份驗證數據” 相結合,避免之前描述的安全/不安全的 servlet 破壞場景。

查看本欄目

防止攻擊

啟用會話安全性實際上可以防止一種攻擊。假設網站在用戶執行身份驗證並使用 HTTPS 之前建立 HTTP 會話(大多數網站都是這樣)。在這種情況下,會話 cookie (JSESSIONID) 是明文的,攻擊者很容易捕獲它。之後,當用戶執行身份驗證時,應該切換到 SSL 並確保只通過 SSL 傳輸 LTPA cookie。問題在於攻擊者已經得到了 JSESSIONID cookie。根據編寫應用程序的方式不同,攻擊者可能能夠使用這個 cookie 和不同的 LTPA cookie(可能是代表他自己的身份的 cookie),作為第一個用戶訪問應用程序。這是一種非常嚴重的攻擊,而且如果使用開放的無線網絡,這種攻擊很容易實現。啟用會話安全性可以阻止這種攻擊,因為應用服務器會阻止訪問不歸當前用戶所有的會話。

8.  注意定制的 JMX 網絡訪問

易受攻擊來源:外部

JMX 和定制的 MBean 讓應用程序能夠支持強大的遠程定制管理。但要注意的是,JMX MBean 可以通過網絡進行訪問。如果選擇部署它們,則需要十分謹慎,確保它們的操作具有合適的授權。WebSphere Application Server 會根據 MBean JAR 文件中的描述符中的信息,自動為 MBean 提供默認的授權限制。這樣是否合適取決於您的應用程序。

設計和實施措施

接下來,我們將注意力轉移到應用程序開發人員和設計人員為了構建安全的應用程序必須采取的措施上。這些步驟非常關鍵,但遺憾的是,它們經常被忽視。

使用 WebSphere Application Server 安全性來保護應用程序

不要依賴於 HTTP 會話跟蹤用戶身份

保護應用程序的每一層

檢驗所有用戶輸入

編寫安全的應用程序

安全地存儲信息

不要審計和跟蹤敏感信息

避免對浏覽器客戶機使用基本身份驗證

避免小部件盜竊:如果使用來自第三方的 GET 構建浏覽器 UI,則使用 SSL

9. 使用 WebSphere Application Server 安全性來保護應用程序

易受攻擊來源:外部

應用程序開發團隊通常能夠認識到他們的應用程序需要某種程度的安全性。這通常是業務上的需求。遺憾的是,許多團隊決定自己開發安全基礎架構。這雖然也有可能做好,但非常困難,而且到頭來,大部分團隊都不能成功。相反,他們的系統看似非常安全,實際上系統安全性非常脆弱。安全性是個很難解決的問題。密碼術的微妙問題、重播攻擊和各種形式的攻擊很容易被忽視。這裡要說的是您應該使用 WebSphere Application Server 安全性。前面曾經建議您啟用應用程序安全性;這裡建議在應用程序中實際使用它。

關於 Java EE 定義的聲明性安全模型,最常見的抱怨可能是它沒有提供足夠的粒度。例如,只能在 EJB 或 servlet 的方法級上執行授權(在這個上下文中,servlet 上的方法是 HTTP 方法之一,比如 GET、POST、PUT 等等),不能在實例級上執行授權。再如,所有的銀行帳號都有相同的安全限制,但是您希望某些用戶對他們自己的帳號擁有特殊權限。

這個問題可以通過 Java EE 安全性 API isCallerInRole 和 getCallerPrincipal 來解決。通過使用這些 API,應用程序可以開發自己強大而又靈活的授權規則,但是仍然需要通過已知的准確信息來驅動這些規則:來自 WebSphere Application Server 運行時的安全性屬性。如果這仍然不夠,可以構建(或購買)更精細的授權框架,框架應該使用應用程序服務器已經維護的現有安全信息(比如組)。即使這仍然不夠,安全基礎架構是高度可定制的。利用(並在需要時擴展)現有的可以正常工作的東西是正確的做法,不應該拋棄現有的東西,嘗試從頭構建安全基礎架構。

一個弱安全性的例子

可以將 WebSphere Application Server 安全性基礎架構和其他身份驗證或授權產品集成。例如,IBM Tivoli Access Manager 可以提供身份驗證和授權支持,IBM Tivoli Security Policy Manager 可以提供更多授權功能。

這裡是一個弱安全性系統的例子。不使用 WebSphere Application Server 安全性的應用程序傾向於創建自己的安全令牌,並在應用程序內部傳遞它們。這些令牌通常包含用戶名和一些安全屬性,比如用戶的組成員身份。這些安全令牌常常沒有可通過密碼學技術驗證的信息。該方法假設可以根據這些令牌中的信息制定安全決策。這是錯誤的。這些令牌只能斷言用戶的特權。這裡的問題是,任何 Java 程序都能夠偽造這些安全對象,然後可以通過後門侵入系統。最能說明這個問題的例子是,應用程序在 servlet 層創建這些令牌,然後將其傳遞到 EJB 層。如果 EJB 層不安全(請參見第 第 11 條),那麼入侵者就可以使用偽造的憑證直接調用 EJB,使應用程序的安全性完全喪失。因此,除非完成細致的工程工作,可靠的用戶信息來源只有 WebSphere Application Server 基礎架構。

10.  不要依賴於 HTTP 會話跟蹤用戶身份

易受攻擊來源:網絡、外部

此建議與上一個主題密切相關。許多自己實現安全性的應用程序通過使用 HTTP 會話來跟蹤用戶的身份驗證會話。這非常危險。該會話是通過(URL 或者 cookie 中的)會話 ID 來跟蹤的。雖然此 ID 是隨機生成的,但它仍然可能遭受重播攻擊,因為它沒有具體的絕對超時時間。只有在一段時間內沒有活動的情況下,才會發生超時,如果截獲了會話 cookie,就能在不受限制的時間段內濫用該 cookie。另一方面,當應用程序使用 WebSphere Application Server 安全性時,會創建 LTPA 令牌,它是更強的身份驗證令牌。特別是,LTPA 令牌的生存期有限,而且使用了強加密,安全性子系統會對可能是偽造的 LTPA 令牌的收據進行審核。

使用 HTTP 會話還有一個更危險、更微妙的安全問題:會話 cookie (JSESSIONID) 通常是在用戶執行身份驗證之前創建的,通常在用戶第一次訪問站點時創建。此時,cookie 常常通過 HTTP 以明文形式發送。在用戶執行身份驗證之後,大多數應用程序會通過 HTTPS 傳輸以後的所有通信流,以保護 cookie 和內容;但是,JSESSIONID cookie 可能已經被盜,因為在最初通過 HTTP 發送該 cookie 時,攻擊者就可以捕獲它。除了盡可能避免使用 HTTP 會話之外,通過啟用會話安全性並將 LTPA cookie 限制為 HTTPS,可以降低 HTTP 會話被盜的風險。

此外,您的應用程序創建的 cookie 應該是安全的(僅限使用 HTTPS),所有 cookie 都應標為 HTTPOnly,但有一個可能的例外(這需要在一次設計審核中備案和簽字批准),那就是,由於客戶機 JavaScript 需要訪問該 cookie,所以應用程序會明確要求它運行。

11. 保護應用程序的每一層

易受攻擊來源:網絡、外部

我們常常采用一定程度的安全性(自制的或者基於 WebSphere Application Server 的)將 Web 應用程序部署在 servlet 層上,但是對應用程序中的其他層卻不加保護。這樣做是基於一個錯誤假設:應用程序中只有 servlet 需要保護,因為它們是應用程序的前門。但是,正如警察常說的那樣,您必須將您家的後門和窗戶都鎖上。在許多場景中都可能出現這種疏忽,但是如果 Java 客戶機不是應用程序的一部分,而是在多層架構中使用可遠程訪問的組件(比如可通過 IIOP 或 Web 服務訪問的 EJB),則最容易出現這種情況。在這種情況下,開發人員常常認為可遠程調用的組件不需要保護,因為根據應用程序設計,它們不是 “用戶可以訪問的”,但這種想法是一個危險錯誤。人們常常開玩笑地將此稱為 “隱藏式安全”。如果不對服務層施加保護,入侵者就可以繞過 servlet 接口,直接進入服務層並進行破壞。

通常,人們對此問題的第一反應就是通過一些平常的手段來保護服務,比如將它們標記為可由所有已通過身份驗證的用戶進行訪問。但是,根據注冊表,“所有已通過身份驗證的用戶” 可能是公司中的每個雇員。一些組織更進一步,將訪問權限制在某個組的成員,這個組指定 “可以訪問此應用程序的所有人”。這樣做好一些,但是通常仍不夠理想,因為能夠訪問應用程序的每個人並沒有必要執行應用程序中的所有操作。解決這個問題的正確方法是在服務中實現授權檢查。對於 EJB,也可以考慮將 EJB 組件實現為只有本地接口,這樣就無法遠程連接它們。

12. 檢驗所有用戶輸入

易受攻擊來源:外部

跨站點腳本是一種相當危險的攻擊,它利用了 Web 浏覽器的靈活性和強大功能。大多數 Web 浏覽器都可以解釋多種腳本語言,例如 JavaScript。浏覽器知道它要根據特殊的轉義字符序列來尋找可執行的代碼。這是 Web 浏覽器的強大之處,也是安全性模型中的一個很危險的漏洞。

入侵者可以欺騙 Web 站點,在浏覽器中顯示入侵者希望該站點執行的腳本,通過這樣做來利用此漏洞。在允許任意用戶輸入的站點上,這很容易做到的。例如,如果站點包含一個用於輸入地址的表單,那麼用戶可以在其中輸入 JavaScript。當站點隨後顯示該地址時,Web 浏覽器就會執行該腳本。該腳本由於來自該站點並在 Web 浏覽器內部運行,所以可以訪問安全信息,比如用戶的 cookie。

到此為止,這看似好像沒什麼危險,但入侵者可以更進一步,他們 欺騙用戶進入一個 Web 站點並輸入惡意腳本,欺騙手段可以是通過電子郵件向用戶發送無害的 URL 或者將 URL 發布在公共博客上。然後,入侵者就可以在用戶的浏覽器中運行任意代碼,通常會訪問 cookie,他們可以看到所有鍵盤活動和顯示的所有頁面。這樣,入侵者就可以對此用戶制造無法挽回的損害。

這個問題實際上是與用戶輸入檢驗相關的問題的一個特例。只要允許用戶輸入任意文本,就必須確保該文本不包含會造成破壞的特殊字符。例如,如果用戶要輸入一個字符串,用它來搜索某個索引,則必須過濾掉可能造成越界搜索的不合適的通配符,這很重要。對於跨站點腳本的預防,需要過濾掉浏覽器支持的腳本語言的轉義字符。這裡要說明的是,對所有外部輸入都應該采取懷疑態度,並仔細進行檢驗。必須解決的問題非常多,對它們的全面討論已超出了本文的討論范圍。

查看本欄目

13. 編寫安全的應用程序

易受攻擊來源:外部

鑒於本文的目標和篇幅,無法在這裡列舉可能影響應用程序安全性的所有應用程序設計和編程問題。如果您對開發安全應用程序很感興趣,請參閱下面這些關於安全應用程序的設計、開發和測試的參考資料:

圖書:Writing Secure Code

圖書:Software Security: Building Security In

OWASP,它發表了以下指南:

Development Guide

Code Review Guide

Testing Guide

Web Application Security Consortium

Penetration testing frameworks

另外,最近發表的一本 IBM 紅皮書 討論了如何使用 IBM Rational AppScan 作為開發周期的關鍵元素,從而構建安全的 Web 應用程序。

14.  安全地存儲信息

易受攻擊來源:機器

要創建安全的系統,必須考慮在何處存儲或顯示信息。有時,一些相當嚴重的安全漏洞就是無意間造成的。例如,對於在 HTTP Session 對象中存儲高度機密的信息,應該十分謹慎,因為此對象可能被序列化到數據庫中,可以從那裡讀取它。如果入侵者可以訪問您的數據庫(甚至是對數據庫卷進行原始計算機級訪問),那麼他就可以看到會話中的信息。毫無疑問,這樣的攻擊需要非常高的技能。

15.  不要審計和跟蹤敏感信息

易受攻擊來源:外部

出於業務目的和調試目的,任何比較復雜的應用程序都會生成豐富的日志和跟蹤信息。這樣做很好,但要記住的是,這些文件中的信息往往保存在許多地方(可能位於您組織之外的地方)。對於非常敏感的信息,不應該進行跟蹤,如果可以,應該試圖避免對其進行審計。例如,我們見過客戶機將用戶的密碼、駕照號碼和社會保險號碼輸出到跟蹤文件中。如果該文件被不當的人(可能是幫助您的顧問)閱讀,就會暴露敏感信息。任何以電子形式(包括備份圖像)從系統發送給任何人的客戶信息都必須是加密的。這一控制級別不僅適用於用戶密碼,也適用於任何客戶信息。

為了確保安全,應該限制並檢查日志記錄的內容。

16. 避免對浏覽器客戶機使用基本身份驗證

易受攻擊來源:外部

基本身份驗證的問題是 Web 浏覽器會緩存用戶 ID 和密碼,在需要的時候,會在以後的請求中自動重新發送它。這意味著使用基本身份驗證的用戶是不可能注銷的。例如,如果用戶的 LTPA 令牌過期了,那麼應用程序服務器會再次詢問用戶 ID 和密碼。浏覽器會重新發送基本的身份驗證標頭,所以超時已經沒有意義了。

這種自動在需要時自動重新發送用戶憑據的現象,實際上存在於大多數單一登錄解決方案的核心,包括基於 SPNEGO 的 SSO,以及用戶使用客戶端 SSL 證書進行身份驗證時。換句話說,基本身份驗證只是讓用戶可輕松地重新登錄,無需手動提供憑據的另一個例子。但是,它不同於其他身份驗證,因為用戶的密碼在每次請求時都會重新發送。

更糟糕的是,如果以後通過 HTTP 發送請求(不加密),浏覽器會通過網絡以明文形式發送密碼。

當客戶機不是浏覽器時,基本身份驗證是合理的方法。例如,Web 服務或 REST 客戶機通常會安全地使用基本身份驗證。當然,這種請求應該通過 SSL 發送。

17. 避免小部件盜竊:如果使用來自第三方的 GET 構建浏覽器 UI,則應使用 SSL

易受攻擊來源:外部

社交媒體站點已滲透到 “傳統的” Web 應用程序中,在此過程中,已經向身份竊賊暴露了您的用戶,向他們提供了用戶的社交媒體憑據。這稱為小部件盜竊。基本場景是這樣的:

一位最終用戶登錄到一個社交站點,比如 Facebook 或 Twitter,但沒有注銷。他或她可能直接關閉浏覽器並重新啟動了計算機。

這位用戶轉移到一個公共 wifi 位置並(使用傳統的 Web 應用程序)訪問他的銀行帳戶。該銀行最近添加了在 Facebook、Twitter 和其他社交媒體站點上 “贊” 該銀行的能力。為了幫助用戶,該銀行的應用程序用戶界面包含無所不在的 Facebook 和 Twitter 圖標。

該銀行的頁面可通過 SSL 呈現,但返回的頁面包含清單 7 中的代碼。            

清單 7
<iframe src="http://www.facebook.com/plugins/like.php?href=YOUR_URL"
scrolling="no"frameborder="0"style="border:none; width:450px; height:80px">
</iframe>

請注意,iframe 會導致向未加密的 URL 發出 GET。

www.facebook.com 的所有 cookie 都通過該 HTTP GET 請求發送,包括包含用戶向 facebook.com 站點驗證的身份的 cookie。

竊聽者 Eve 監聽著可通過 wifi 看到的未加密的流量,並獲取了未加密的 cookie。

結合利用社交媒體登錄來進行身份驗證的第三方應用程序,這會變成一個比您最初想象的更大的風險。已經有一些浏覽器插件設計用來保護用戶,但需要一位知識淵博的用戶來安裝和啟用這些插件。

我不是提倡您不要將您的應用程序與這些社交媒體站點相集成,或者提倡您的用戶不應向這些站點發送一個 “贊”。但是請負起責任:將獲取該內容的代碼更改為清單 8 中所示的代碼。
清單 8

<iframe src="https://www.facebook.com/plugins/like.php?href=YOUR_URL"
scrolling="no"frameborder="0"style="border:none; width:450px; height:80px"></iframe>

高級注意事項

現在,我們繼續討論一些與安全性加強相關的高級問題,包括跨計算單元信任、應用程序隔離、身份傳播和 WebSphere Application Server 安全性中的限制。在大多數情況下,這裡並沒有給出具體的建議,而是提供一些重要的信息,幫助您維護和管理安全的基礎架構。
計算單元信任和隔離

WebSphere Application Server 計算單元不應跨越信任邊界。如果不能完全信任某些人,則不要讓他們管理您的計算單元或管理計算單元內的計算機。WebSphere Application Server 管理基礎架構不考慮細粒度的管理安全性,而是在整個計算單元范圍內每個 WebSphere 進程之間采取粗粒度的共享信任模型。每個應用程序服務器都包含管理基礎架構,包括內部 API。從積極的方面講,這消除了共同的控制和故障點,使得應用服務器具有很高的獨立性和穩定性,但是這也對隔離有負面影響。這種方法的影響包括:

WebSphere Application Server 計算單元中的每個應用程序服務器都對整個計算單元具有完全的管理權限。如果任何應用程序服務器被攻破,那麼所有應用程序服務器都會被攻破。

物理計算機邊界(獨立的計算機、LPAR、節點等等)幾乎對計算單元安全性沒有任何影響。計算單元中的信任單元是所有節點上的所有應用程序服務器。

進程邊界對計算單元安全性幾乎沒有影響。從安全的角度來看,將應用程序放在單獨的應用程序服務器 JVM 中對增強計算單元內的隔離性並沒有太大用處。

單獨的操作系統標識對計算單元的安全性幾乎沒有影響。由於應用程序服務器使用各種協議與計算單元的其他部分進行通信,而這些協議不由操作系統管理,因此一般的操作系統保護措施沒有效果。

這就引出了兩個關鍵主題:管理隔離和應用程序隔離。
管理隔離

對於 WebSphere Application Server,在默認情況下所有管理員都對整個計算單元具有管理權限(根據分配給他們的角色)。在 WebSphere Application Server V6.1 中增加了一個稱為授權組的新特性,因此可以采用更細的粒度(服務器、應用程序、節點、集群等等)授予管理權限。在 V6.1 中,注冊授權組的定義只由 wsadmin 支持。在 WebSphere Application Server V7 中,管理控制台也支持它們。如果您的計算單元很大,有許多管理員,那麼應該考慮使用這些功能。
應用程序隔離

在此上下文中,應用程序隔離基本上是關於如何防止一個應用程序的惡意操作對另一個應用程序造成損害。此類攻擊很難避免。現實情況是,基礎架構軟件產品(比如 Java EE 應用程序服務器)尚未達到多用戶操作系統的成熟水平。它們無法提供操作系統通常在多個用戶之間提供的可靠隔離。

查看本欄目

這會影響您嗎?

首先也是最重要的,此處討論的缺陷都只是內部缺陷。只有安裝到計算單元中的應用程序才能利用這些缺陷。根據 IBM 的經驗,絕大部分 WebSphere Application Server 用戶(甚至包括使用共享基礎架構的用戶)都不受這些問題影響。這是因為他們認識到了其共享基礎架構位於企業內部,運行的是得到企業認可的代碼。因此,他們通常不要求應用程序實現完全的安全隔離。

受到此處的問題影響的 WebSphere Application Server 用戶通常具有非常嚴格的安全策略,例如:

具有正式的策略,要求應用程序不能訪問其他應用程序的數據,即使它們在共享基礎架構中運行。

對每個應用程序在共享服務器上以單獨的用戶 ID 運行(企業中早於 WebSphere Application Server 的系統的常見要求)的要求,詳細地規定關於文件系統權限的規則,每個應用程序都具有專用進程,並嚴格執行針對這些要求的審計過程。

具有嚴格的企業安全方針,嚴格執行這些方針,確保它們得到了遵從,這些方針中很可能包括應用程序架構和代碼檢查。如果沒有代碼檢查,開發人員可能會插入違反企業策略的代碼。

設計策略,確保可能損害一個應用程序的遠程攻擊無法用來損害其他應用程序。

如果您的環境沒有這些特點,那麼本節中的問題對您不適用,可以 跳到下一節。

可以采取何種緩解措施?

可以采取以下緩解措施:

對所有應用程序代碼執行嚴格的代碼檢查。最好配合使用源代碼管理系統。這樣,對於每次代碼更改,都會跟蹤進行更改的人員,並針對每次代碼更改安排和跟蹤代碼檢查。在這種情況下,單個程序員不可能將惡意代碼插入到您的系統中。相反,進行任何破壞都需要多人合作。我們認為這相當重要,因為即使實現了應用程序隔離,惡意的應用程序代碼也很容易在單一應用程序中造成嚴重的損害。

如果您選擇購買在 WebSphere Application Server 上運行的商業應用程序,請確保僅從可靠的、值得信任的供應商處購買,對應用程序進行細致的測試和監視,然後再進行生產部署,並在生產環境中對其進行監視。

如果確實有必要,則應將應用程序部署到私有的 WebSphere Application Server 計算單元中。可以考慮根據風險和信任程度,對不同的業務單位或其他組織單位使用不同的計算單元。為了限制硬件成本,可以在單一計算機或 LPAR 上安全地運行來自多個計算單元的節點。只需使用不同的操作系統用戶 ID、不同的加密密鑰和不同的管理密碼運行每個計算單元即可。從安全角度而言,這將提供完全的隔離。

如果這些方法都無法接受,那麼可以對基礎架構采用應用程序隔離加強技術。請注意,這些技術都要求做大量的工作。更重要的是,它們不能保證提供隔離。在同一個計算單元中的應用程序(即使啟用了管理安全性、應用程序安全性和 Java 2 安全性)可能會訪問其他應用程序的資源或改變計算單元配置,從而損害同一計算單元中的其他應用程序。無法保證不會出現此類破壞。

清單 9 中的代碼演示了需要執行代碼檢查來實現有效的安全性的另一個例子。
清單 9

Map<String, String> map = newHashMap<String, String>();
map.put(Constants.MAPPING_ALIAS, "cesar-pcNode03/apstsegu");
CallbackHandler callbackHandler = 
    WSMappingCallbackHandlerFactory.getInstance().getCallbackHandler(map,null);
    
LoginContext loginContext = newLoginContext("DefaultPrincipalMapping", callbackHandler);
loginContext.login();
    
Subject subject = loginContext.getSubject();
Set<Object> credentials = subject.getPrivateCredentials();
    
PasswordCredential passwordCredential = (PasswordCredential) 
    credentials.iterator().next();
    
String user = passwordCredential.getUserName();
String password = newString(passwordCredential.getPassword());

這段代碼利用一個 WebSphere Application Server 安全性 SPI 來獲取計算單元中任何 J2C 別名的用戶 ID 和密碼。因為此 SPI 的用途是用於應用程序安全性上下文擴展和自定義,所以該 SPI 必須能夠訪問這部分敏感的安全信息。結果是,阻止惡意代碼利用此插入點(和其他類似插入點)的惟一方式是執行代碼檢查,確保應用程序不使用插入點,除非業務需求要求使用它們。

發出了這些警告之後,下面幾節將繼續討論可以顯著提高計算單元內的應用程序安全隔離的措施。您可能很快發現這些措施很難實施,而且成本非常高。更好、成本更低的方法是,通過嚴格的雇員管理、代碼檢查和其他管理控制機制,確保您的應用程序開發人員交付可信的代碼。與前面一樣,這些措施的優先次序如下。

不要在 Java EE 資源上指定組件管理的別名

不要在資源上定義默認的用戶 ID 和密碼

Java 2 安全性

利用安全連鎖委托

保護 TAM WebSEAL TAI 密碼

注意定制 JMX 代碼中提升的權限

謹慎地使用 DynaCache

小心地使用所有資源

1.  不要在 Java EE 資源上指定組件管理的別名

易受攻擊來源:內部

在計算單元內運行的任何 Java EE 應用程序都可能訪問任何 Java EE 資源。這是因為資源具有 JDNI 名稱,而任何應用程序都可以查詢此名稱,而且對於資源訪問沒有授權機制。因此,如果應用程序 A 要使用企業數據庫,只需將該數據庫定義為數據源,同一計算單元中的應用程序 B 就可以訪問此數據庫。

當應用程序試圖通過調用資源工廠(例如數據源或 JMS 連接工廠)上的 getConnection() 來訪問資源時,如果相應的底層資源可用,那麼 WebSphere Application Server 會隱式地向底層資源提供身份驗證信息。提供何種身份驗證信息取決於身份驗證模式和可用的 J2C 身份驗證別名。具體的細節非常復雜,但簡單來說,任何應用程序都可以查找 JNDI 名稱空間中的任何資源。完成此工作後,將隱式地使用 “應用程序” 的身份驗證模式。這又意味著 WebSphere Application Server 將使用組件管理的身份驗證別名(如果有的話)。因此,計算單元中的任何應用程序都可以訪問任何使用組件管理的別名定義的資源。請注意,在不同的范圍內定義資源對安全性並沒有影響。資源范圍僅僅是方便管理的機制。

另一方面,如果只在資源上定義容器管理的別名(或者不指定別名),那麼惡意應用程序就無法訪問此資源,因為當在全局 JNDI 名稱空間中查找資源時,將使用應用程序身份驗證,因此會使用組件管理的別名。因為沒有組件管理的別名,所以無法完成隱式身份驗證。

如果您選擇采用此方法,顯然仍然希望恰當的應用程序能夠訪問這些資源。為此,這些應用程序必須在其部署描述符中指定用於訪問資源的本地資源引用。然後可以在部署時將這些引用綁定到正確的資源。如果應用程序在引用上指定了容器管理的身份驗證,則將隱式地使用在資源本身上定義的容器管理的別名。這種情況可以使用一張圖加以說明。圖 3 顯示 IBM Rational Application Developer 引用編輯器,其中在一個 JMS 連接引用上指定容器管理的身份驗證。

圖 6. 使用容器管理的身份驗證的數據庫資源引用

圖 6. 使用容器管理的身份驗證的數據庫資源引用

這種方法有兩個問題。首先,在 WebSphere Application Server V6.1 中,容器管理的別名已經被錯誤地否決了(但是在 V7 中不再被否決)。其次,也是更重要的,您可能已經注意到,並非所有的資源都允許指定容器管理的別名(例如 V6.1 中的 JMS 工廠)。在這種情況下,一定不要在資源上提供默認身份驗證信息。必須在應用程序中為每個資源引用指定身份驗證信息(在這裡身份驗證方法並不重要),比如在部署期間。此工作非常單調乏味,但是可以使用 wsadmin 自動執行。至少對於 MDB,可以在激活規范中指定身份驗證信息。

查看本欄目

XA 恢復別名不是問題

不要將組件管理的別名與資源上指定的 XA 恢復別名相混淆。XA 恢復別名僅在涉及到事務故障的某些恢復場景中使用。如果啟用 Java 2 安全性並使用默認權限,那麼應用程序通常無法訪問該別名。

2. 不要在資源上定義默認的用戶 ID 和密碼

易受攻擊來源:內部

前一條的一個推論是,不應在資源上定義默認的用戶 ID 和密碼。如果這樣做,那麼計算單元內的任何應用程序都可以查找該資源,然後隱式地使用所提供的用戶 ID 和密碼。

3. Java 2 安全性

易受攻擊來源:內部

正如在前面討論的,所有應用程序服務器均包含 WebSphere Application Server 管理基礎架構,因此也包含用於執行大部分管理操作的 API。學習了這些 API 的應用程序員可以編寫調用其中任何 API 的應用程序,因而實質上可以執行任何管理操作。此外,文件系統配置存儲庫包含大量敏感信息(如密碼)。任何應用程序都可以使用普通 Java I/O 來讀取這些文件。

正如在前面討論的,所有應用程序服務器均包含 WebSphere Application Server 管理基礎架構,因而也包含用於執行大部分管理操作的 API。學習了這些 API 的應用程序員可以編寫調用其中任何 API 的應用程序,因而實質上可以執行任何管理操作。此外,文件系統配置存儲庫包含大量敏感信息(如密碼)。任何應用程序都可以使用普通 Java I/O 來讀取這些文件。但是,如果不通過正式的過程檢查授予的權限,那麼使用 Java 2 安全性就沒有什麼價值,實際上,如果啟用它而不檢驗策略文件,情況會變得更糟糕,因為安全性並未提高,而應用程序開發更困難了,性能也會略微降低。

一旦啟用了 Java 2 安全性,在默認情況下,應用程序就被限制為僅使用很小的 “安全的” 權限集。如果應用程序需要更多的權限,它通常必須在 EAR 內包含的 was.policy 文件中定義這些權限。應用程序在運行時會讀取 was.policy 文件,並將這些權限添加到標准集中。顯然,這是一個潛在的安全漏洞。為了讓這種機制正常發揮作用,需要通過嚴格的、定義良好的過程決定、檢查和實施每個應用程序的 Java 2 權限。如果任何應用程序試圖請求不可接受的權限(即使在處理緊急情況期間),則應拒絕它。應該有一個正式的過程,其中包含判斷允許應用程序具有哪些權限的安全檢查。即使有正式的過程,啟用 Java 2 安全性也應該小心謹慎;除了需要多做一些工作之外,強制啟用 Java 2 安全性常常導致使用不適當的策略文件,為了實現部署,這些策略文件往往很少提供有意義的保護。這不但要多做一些工作,還會產生虛假的安全性。

安裝時的檢查和檢驗過程可能十分單調乏味。不過,可以采用另一種方法。首先,對於很多環境而言,大部分應用程序都需要一個公共附加權限集。如果可以這樣做,那麼基礎架構團隊可以在節點上的 app.policy 文件中為所有應用程序設置默認權限。只有需要不常用的權限的應用程序才需要將所需權限放置在 was.policy 中,並進行額外的檢驗。您甚至可以進一步設置一些限制,禁止使用 was.policy,並要求由管理團隊將所有權限添加到 app.policy 中。這在某種程度上會使得部署變得復雜(需要編輯一個公共文件),但可以減少應用程序獲得不恰當權限的風險。

對此方法的一項完善是在不同的生命周期環境中以不同的方式指定 Java 2 安全性。

在開發環境中,啟用 Java 2 安全性,定義自定義屬性 com.ibm.websphere.java2secman.norethrow=true。這會導致日志出現關於需要哪些 Java 2 安全性權限的警告,但不會拋出任何 Java 2 安全性異常。

在測試環境中,啟用 Java 2 安全性,但沒有定義該自定義屬性。如果應用程序沒有包含必要的策略文件,那麼這些應用程序就不會運行。在測試環境中,對可接受策略文件所做的更改必須按上述方法嚴格審查。

在生產環境中,不要啟用 Java 2 安全性,這會避免性能開銷。僅將在測試中通過了審查的應用程序部署到生產環境中。

請注意,這項完善不會減少審核對驗證策略更改的需求。

(啟用 Java 2 安全性會帶來不小的運行時性能成本。兩個非常重要的安全性自定義屬性可減少這一成本(但不會完全消除它)。它們是 com.ibm.websphere.security.auth.j2c.cacheReadOnlyAuthDataSubjects=true 和一個適當調優的 com.ibm.websphere.security.auth.j2c.readOnlyAuthDataSubjectCacheSize。請在 信息中心 中查閱這些屬性。)

4.  利用安全連鎖委托

易受攻擊來源:內部

應用程序服務器的好處之一就是,會自動在系統層之間和跨應用程序發送用戶身份信息。這就實現了透明的單點登錄 (SSO)。不過,這有一個可能非常危險的副作用:不恰當模擬。

此處的問題是,當用戶為了使用應用程序 A 而進行身份驗證時,應用程序 A 可能對應用程序 B 進行遠程 EJB 調用。這樣,應用程序 B 就會看到原用戶的憑證。通常,這沒有什麼問題。但是,如果應用程序 A 不可信呢?在這種情況下,訪問應用程序 A 的用戶就有理由擔心別人會通過模仿以此用戶的名義訪問應用程序 B。設想一下,假如應用程序 A “不重要”,因此是采用臨時拼湊的方式開發的;而應用程序 B 是管理機密信息的高度敏感的應用程序。此處的問題是,因為應用程序 B 與應用程序 A 共享一個公共安全域,所以必須信任應用程序 A。這種做法非常不好。

有一個辦法可以解決此問題。可以使用 WebSphere Application Server 中的一個特性,此特性被大致描述為 “安全連鎖委托”。通過使用 WSSecurityHelper.getCallerList() 或 getServerList(),應用程序 B 可以確定請求經過了哪些應用程序和服務器。如果應用程序 B 是高度敏感的應用程序,可能要求它將該列表設置為空,表示它由用戶直接使用。關於 WSSecurityHelper 的更多信息,請參閱 WebSphere Application Server 信息中心。

5.  保護 TAM WebSEAL TAI 密碼

易受攻擊來源:內部

當在 Tivoli Access Manager WebSEAL 和 WebSphere Application Server 之間配置了 SSO 時,WebSEAL 會在每個請求的 HTTP 標頭中發送其保密密碼,以確保 TAI 在調用時能正常工作。雖然由於連接應該使用 SSL 進行加密,所以通常這不是什麼問題,但這樣的確會向 WebSphere Application Server 中運行的 Web 應用程序公開 WebSEAL 密碼。(盡管本節專門討論 WebSEAL TAI,但是通過發送密碼來建立信任的任何 TAI 都會發生這種情況。)

首選的方法(如 第 1 部分 中所述)是使用 Enhanced Tivoli Access Manager TAI 代替 WebSEAL TAI,不使用秘密密碼來建立信任。

如果運行在 WebSphere Application Server 中的某個 Web 應用程序不可信,那麼它可能會獲取此密碼,然後打開到某個應用程序服務器的 HTTP 連接,並斷言任何用戶的身份。這樣,精心編寫的惡意應用程序就可以冒充任何人進行操作了。

如果擔心出現這種類型的攻擊(可以通過代碼檢查輕松地防止),那麼可以阻止任何不可信的客戶機連接到 Web 容器。為此,只需在 Web 容器上配置一個相互身份驗證的 HTTPS 監聽器即可,請參閱 第 1 部分 中的說明。這樣,惡意應用程序就無法打開到 Web 容器的 HTTPS 連接,因為它們沒有正確的私鑰(只有 WebSEAL 或 Web 服務器擁有此私鑰)。

6. 注意定制 JMX 代碼中提升的權限

易受攻擊來源:內部

對於 Mbean,需要注意一點是:要想使用它們,就必須提升 Java 2 安全性權限。如果應用程序以編程方式向應用服務器運行時注冊 Mbean,則必須向發出調用的代碼,授予提升的管理權限。進行此操作時需格外小心。這種權限可用來執行非法管理操作。一種不錯的方法是創建一個專門用於注冊 Mbean 的單獨模塊,並僅授予此模塊所需的權限。

第二種裝載 MBean 的方法是以管理方式將其指定為 Extension Mbean(這是推薦的方法)。這樣就消除了必須顯式地授予應用程序代碼管理權限的問題,但又出現了一個新問題:MBean 現在由相當低層的 WebSphere Application Server 類裝載器進行裝載,此裝載器的信任度更高。因此,與采用普通用戶代碼相比,MBean 具有更多訪問 WebSphere Application Server API 的權限。

如果選擇開發定制的 Mbean,必須仔細地對代碼及其使用情況進行檢查,確保不會給系統帶來安全漏洞。

7.  謹慎地使用 DynaCache

易受攻擊來源:內部

DynaCache 為 WebSphere Application Server 應用程序提供了分布式共享緩存。不過,DynaCache 上並沒有訪問控制機制;在應用程序服務器中運行的任何應用程序都可以訪問此應用服務器具有訪問權限的任何緩存。更准確地說,任何應用程序都可以訪問服務器能夠訪問的任何緩存,可以看到(或修改)緩存的所有內容。

有兩種緩存需要考慮。應用程序服務器本身維護一些隱藏的內部緩存(servlet 緩存、Web 服務緩存和安全緩存),其中可能包含敏感信息。還有用戶創建的緩存,比如可以通過 JNDI 訪問的 Object Cache。

內部緩存並不在 JNDI 中注冊,所以更難找到它們,但是可以通過使用內部 API 訪問它們。從積極的方面來看,在默認情況下這些緩存只復制到同一集群中的服務器,所以可以確信不同集群中的應用程序無法看到其他集群的緩存內容。

用戶定義的緩存可以在 JNDI 中看到,可以在同一計算單元中的任何服務器上查找它們。查找到緩存之後,應用程序就可以修改或讀取緩存。無法防止這種行為。因此,如果關心應用程序隔離,就不要使用用戶創建的緩存。

8. 小心地使用所有資源

易受攻擊來源:內部

其他很多 WebSphere Application Server 資源(如工作區)並沒有提供應用程序級的授權。與 DynaCache 一樣,您必須小心地使用這些資源。如果關心應用程序隔離,則應該仔細地對每個使用場景進行評估,查找潛在的漏洞並采取相應措施。

查看本欄目

跨計算單元的信任

通常,WebSphere Application Server 計算單元並不是彼此信任的,因此不可能實現跨計算單元的 SSO。不過,可以對計算單元進行配置,使其支持跨計算單元 SSO。這麼做有充足的理由,但是在這麼做時,實際上是在擴展計算單元的信任域,需要注意對安全的潛在影響。您需要考慮三個問題:

通常,域就是一個注冊表。WebSphere Application Server V6.0.2 和更高版本放寬了這個規則,可以獨立於注冊表指定域名稱。

共享 LTPA 密鑰

要想讓兩個計算單元透明地參與 SSO 域,則必須讓它們共享兼容的域(在 WebSphere Application Server V6.1 中這意味著同一個域,在 V7 中意味著可信域)、共享相同的 LTPA 加密密鑰,並使用兼容的 SSL keyring(供服務器用於服務器通信)。兼容的 SSL keyring 意味著,與任何 SSL 通信一樣,發出調用的服務器必須能夠訪問與接收調用的服務器的證書對應的簽名證書。

一旦確保兩個計算單元共享了相同的 LTPA 加密密鑰,就創建了一個特殊的環境,此環境中的每個計算單元都可以為其他計算單元創建憑證,包括管理憑證。因此,如果一個計算單元被攻破,那麼兩個計算單元都會被攻破。如果使用多個計算單元,並且由於安全原因需要實現應用程序隔離,那麼需要啟用 Java 2 安全性來限制對 WebSphere Application Server 內部 API 的訪問。

如果共享相同的 LTPA 加密密鑰只是為了創建 Web SSO,而不需要共享定制的主題,那麼可以通過使用身份驗證代理服務器(比如 Tivoli Access Manager WebSEAL)和一個相應的 TAI(比如 Extended TAM TAI)實現相同的結果,而不必共享 LTPA 加密密鑰。通過一個代理和一個 TAI 實現 Web SSO 是共享 LTPA 密鑰的首選方法。

CSIv2 身份斷言

如果要進行跨計算單元的 IIOP 調用,但希望避免共享 LTPA 加密密鑰,這是完全可以實現的。為此,必須使用 CSIv2 身份斷言(當與非 WebSphere Application Server EJB 服務器進行聯系時,這也很有用)。

讓我們考慮一個簡單的場景:假定有兩個計算單元(A 和 B),它們均包含多個服務器。假定計算單元 A 中的服務器需要對計算單元 B 中的服務器進行 RMI/IIOP 調用,但不會進行相反的調用。為了實現此功能,需要配置 CSIv2 身份斷言。計算單元 A 中的服務器將向計算單元 B 中的服務器斷言身份。這裡不描述如何配置 CSIv2 身份斷言,只討論這樣做的影響。

為了讓計算單元 B 中的服務器接受身份斷言,計算單元 A 中的上游服務器必須首先對自身進行身份驗證。可以采用兩種方式來對 CSIv2 進行此操作:基本身份驗證(上游服務器發送其用戶 ID 和密碼)和客戶機證書身份驗證(上游服務器使用自己的證書進行身份驗證)。

身份驗證完成之後,接受調用的服務器將檢驗上游服務器是否可信,是否可以執行身份斷言。這是在 CSIv2 配置面板中配置的。此後,上游服務器向下游服務器發送目標用戶的身份信息。

讓我們考慮一下此方法的信任影響。計算單元 B 中的服務器接受來自計算單元 A 的身份斷言,因此信任計算單元 A。如果計算單元 A 被攻破,則計算單元 B 也會被攻破,但對於計算單元 A 有何影響呢?

如果計算單元 A 發送服務器用戶 ID 和密碼來建立信任(這是默認行為),這會讓計算單元 B 中的服務器知道其服務器用戶 ID 和密碼,而此用戶 ID 具有完全的管理權限。因此,計算單元 A 現在完全信任計算單元 B。與只共享 LTPA 密鑰相比,這並未提高安全性。

如果計算單元 A 發送一個指定的用戶 ID 和密碼(此 ID 只用於此用途),就不會向計算單元 B 公開重要的信息。計算單元 A 不信任計算單元 B。

如果計算單元 A 使用自己的證書進行身份驗證,則不會向計算單元 B 公開任何內容。計算單元 A 不信任計算單元 B。

總之,為了讓計算單元 A 對計算單元 B 斷言身份,計算單元 B 必須信任計算單元 A。這非常明顯。如果不希望計算單元 A 信任計算單元 B,則應該在服務器到服務器身份驗證步驟中使用指定的用戶 ID 和密碼或證書身份驗證,而不是使用默認的方式(發送服務器 ID 和密碼)。

主題傳播回調

如果要使用跨計算單元 主題傳播,則必須注意計算單元還可能相互進行帶外調用來獲取主題。為了說明這一點,我們來考慮一個例子:假定有兩個服務器共享一個 SSO 域。某個用戶使用 Web 浏覽器訪問服務器 A 並獲得了一個身份驗證會話(在浏覽器中由 LTPA cookie 表示)。該用戶隨後訪問服務器 B。服務器 B 將試圖從服務器 A 獲取該用戶的主題。這稱為主題傳播。如果這些服務器位於相同的 DynaCache 復制域中,則很容易完成此操作。如果它們不位於相同的 Dynacache 復制域中,則使用 JMX 回調來獲取主題。當然,不同計算單元中的服務器不處於相同的 DynaCache 復制域中。因此,在這個示例中,服務器 B 將對服務器 A 進行安全 JMX 調用,以獲取用戶的主題。

與任何管理調用一樣,JMX 調用需要進行身份驗證和授權。在這種情況下(從 WebSphere Application Server V6.1 開始),通過使用共享的 LTPA 密鑰隱式地建立信任。因為服務器 B 與服務器 A 共享 LTPA 加密密鑰,所以服務器 A 信任它,會提供主題信息。

總而言之,除了由於共享 LTPA 密鑰已經引入的風險之外,回調並不會顯著影響安全性,但是它們引入了另一個網絡路徑,一些人可能認為這是風險。

這並不適用於出現使用 IIOP 的下游傳播時。在這種情況下,上游服務器會直接將主題發送到下游服務器。不需要進行 JMX 回調。

身份傳播

雖然此主題與安全性加強並不直接相關,但它是一個在系統設計中經常出現且沒有盡早考慮安全性的問題。必須始終非常謹慎地對在何處建立身份以及如何傳播身份(如果可以傳播)進行跟蹤。我們見過很多設計直接假設身份是已知的,而實際技術卻使這不可行。要確保對應用程序中的身份流進行仔細的分析,以防止在後面的開發周期造成大麻煩。下面給出涉及到外部資源和解決方案(對於 WebSphere Application Server V6 和更高版本)的兩種常見情況。

數據庫與 WebSphere Application Server 身份驗證

企業系統的主要挑戰之一就是恰當地實現強大的系統安全控制。簡單來說,需要用恰當的授權保護關鍵數據。對於多層 Java EE 系統(其中的 Java EE 應用程序代碼會訪問數據庫,比如使用 JDBC、SQLJ、JPA 或 CMP bean)來說,這個挑戰尤其難以解決,因為用戶的身份信息通常會丟失。這裡的 “用戶” 指的是應用程序代表其進行操作的用戶;也就是說,如果 Bob 使用標准 Java EE 安全性向應用程序進行身份驗證,那麼 Bob 就是用戶。

在典型的基於 Java EE 的系統中,容器維護一個經過身份驗證的連接池。每個用戶都會經過應用程序服務器的身份驗證(使用幾種 Java EE 身份驗證機制之一),但用戶的身份信息對數據庫是不可用的。這是因為所有數據庫訪問都是使用連接池中的公共共享連接之一執行的。在過去,這導致應用程序不得不在應用層內重新實現現有的數據庫級授權和審計功能。即使處理得當,也會浪費資源,而在處理不得當時,很可能非常不安全。

在 WebSphere Application Server V6 中,對此問題有一個 精致的解決方案。V6.1 中提供了把身份傳播到 IBM DB2 的機制。

MDB 不以排隊者的身份運行

當消息在消息傳遞系統中排隊時,原始調用者的身份通常不會與其相關。也就是說,消息傳遞引擎根據前面討論的連接身份授權對隊列的訪問。隊列通常甚至不會記錄最終用戶的身份。

當消息離開隊列時(在 Java EE 中通常由 MDB 將消息從隊列取出),原始調用者的身份不可用 —— 即使此信息可用,也會被忽略。MDB 以匿名 Java EE 身份或靜態 run-as 身份運行。它們不會以消息排隊者的身份執行。

在 WebSphere Application Server 中沒有用於處理此問題的直接支持。不過,如果您願意編寫一些定制的代碼,那麼可以解決此問題。從 WebSphere Application Server V6.0.2 開始,WebSphere Application Server 支持服務器端身份斷言。也就是說,服務器端代碼可以使用 JAAS 更改其 Java EE run-as 身份,不需要提供密碼。它直接斷言用戶身份信息。下面是一個使用 Java 代碼實現此功能的簡單示例:

清單 10
CallbackHandler wscbh = 
    WSCallbackHandlerFactory.getInstance().getCallbackHandler(username, null);
LoginContext lc = newLoginContext("system.RMI_INBOUND", wscbh);
lc.login();

請注意,這裡沒有提供密碼。

這可以與 關於高級身份驗證的這篇文章 中的思想相結合,以斷言定制的主題。按照 這篇信息中心文章 中的描述,還可以讓 WebSphere Application Server 創建 LTPA cookie,讓 Web 應用程序能夠實現這個功能。

很明顯,這存在嚴重的安全隱患,因此在使用 Java 2 安全性時在默認情況下這個調用被阻止。但是,通過向應用程序代碼授予所需的 Java 2 安全權限,就可以使用它。

WebSphere Application Server 限制

一般來說,通過仔細地進行配置,可以使用 WebSphere Application Server 創建高度安全的健壯的環境。不過應該注意,一些通常很小的、不太明顯的限制可能會對您有所影響。

查看本欄目

目標身份未經檢驗

安全系統的一個非常微妙的方面是檢驗請求目標的概念。通常,當提到身份驗證時,我們會想到服務器驗證客戶機的身份,但客戶機如何驗證服務器的身份呢?客戶機如何知道服務器確實是它所期望連接的服務器呢?大部分人沒有認識到這一點,但 Web 浏覽器每天都會隱式地執行此項檢查。當使用 HTTPS 時,Web 浏覽器將會檢驗 Web 服務器的主機名是否與其證書中的 Web 服務器的主題相同。這可以確保服務器確實是用戶所希望連接的服務器(當然,假定用戶知道他們使用的主機名;很多人並不這樣細心)。

不太明顯的是,Web 浏覽器執行的此項檢查並不是 SSL 的固有部分,而是在 SSL 之外執行的特定於浏覽器的檢查。發起方(發出調用的服務器)必須明確地對證書執行此檢查。WebSphere Application Server 並不執行此檢查。因此,當應用程序服務器(或客戶機)打開到服務器的 SSL 連接時,它並不能確信該服務器就是希望使用的服務器。盡管可能性很小,但是如果黑客可以攻破您的內部 DNS 或網絡,就可以在 WebSphere Application Server 計算單元中插入一個欺詐服務器並竊取信息。這是一種異常困難的攻擊(很多其他攻擊要簡單得多),但應當注意這種可能性。

可以從應用程序服務器信任存儲文件中刪除任何不需要的簽名密鑰,以防止出現這種情況。只有使用可信的簽署者頒發的證書才能發起這種攻擊。在 SSL 握手期間,客戶機會拒絕無法檢驗的服務器端證書。如果可信列表很小(或許僅包含自簽名證書),則發起此類攻擊會非常困難。因為信任存儲在默認情況下不包含任何 CA 簽署者,默認簽署者惟一要關注的是,如果在共享的計算單元信任存儲中添加 CA 簽名證書,則會遇到這種風險(盡管風險不大)。

保護桌面開發環境

在考慮安全性加強時,大多數人習慣於將注意力集中在生產系統上,生產系統自然是最重要的。不過,您也應該花一些時間來確保其他計算機(包括桌面系統)也具有合理的安全性。

對於這些運行 Rational Application Developer(或早期的 WebSphere Studio)的計算機,這是一個非常重要的問題。桌面 IDE 包含一個功能齊全的嵌入式 WebSphere Application Server 運行時環境。此應用程序服務器具有開放的端口,易於受到本文前面描述的各種方式的遠程訪問攻擊。需要對此進行保護。
加強嵌入式應用程序服務器

至少應該在嵌入式應用程序服務器測試環境中啟用管理安全性。Rational Application Developer 7.5 在默認情況下已經啟用了管理安全性。這可以防止最嚴重的攻擊類型,其中入侵者可能使用內置的管理基礎架構將惡意應用程序部署到您的桌面上。如果使用一個具有管理權限的操作系統用戶 ID 來運行 Rational Application Developer,這相當重要。您可能還希望采取本文中提到的其他加強步驟,不過確保管理基礎架構的安全是最為重要的步驟。

加強嵌入式應用程序服務器的另一種方法是安裝桌面防火牆產品,阻止對您計算機的訪問。如果配置得當,此方法會非常有效。但是,信任整個內部企業網絡的防火牆在此場景中幾乎沒有價值。

從以前的版本遷移

在 WebSphere Application Server 的不同版本之間遷移可能導致向後兼容性問題。從安全性的角度來看,推薦的應用程序遷移方法是從頭構建一個完整的新計算單元,然後在新的計算單元中安裝應用程序(當然先要進行嚴格的測試)。通過采用這種方法,可以受益於新版本的所有默認配置更改。

如果使用 WebSphere Application Server 計算單元遷移工具,它們會把現有的配置和應用程序復制到新的計算單元,因此不會受益於每個主要版本對安全性的許多改進。這是因為我們會盡可能少修改現有的配置,以確保應用程序能夠繼續正常運行。這麼做的副作用是加強默認安全性的配置更改不會生效。因此,如果使用工具從 WebSphere Application Server V6 遷移到 V7,那麼應該閱讀本文的 V6 和 V7 版本,而不只是最新版本。

結束語

這篇由兩部分組成的文章討論了大量內容。雖然我們討論了有關安全性的很多方面,但是重點放在加強 WebSphere Application Server 環境這一核心主題上。希望您已經獲得了保證 Java EE 系統安全所需的基本信息。本文的內容並不全面,您應當從其他信息源查找關於加強基礎架構的其他部分的信息。WebSphere Application Server 只是冰山的一角。

您可以使用一個稱為 IBM Security Scanner for WebSphere Application Server 的自動化工具對本文中所描述的一部分事項進行檢查,可以 下載 這個工具。

最後,如果希望進一步了解 WebSphere Application Server 安全性,請聯系 IBM Software Services for WebSphere,參加關於 WebSphere Application Server 安全性的定制的現場課程。這個課程深入講解安全性加強、定制身份驗證、集成、單點登錄和各種其他相關主題。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved