關於Java的web.xml文件中配置認證和授權有大 量 的 文章。本文不再去重新講解如何配置角色、保護web資源和設置不同類型的認證,讓我們來看看web.xml文件中的一些常見的安全錯誤配置。
(1) 自定義的錯誤頁面沒有配置
默認情況下,Java Web應用在發生錯誤時會將詳細的錯誤信息展示出來,這將暴露服務器版本和詳細的堆棧信息,在有些情況下,甚至會顯示Java代碼的代碼片段。這些信息對為他們的病毒需找更多信息的黑客來說是一種恩惠。幸運的是,通過配置web.xml文件來展示自定義的錯誤頁面是非常容易的。使用如下的配置后無論服務器在任何時候發生HTTP500錯誤,一個非常好的錯誤頁面就會被顯示出來。你可以為HTTP狀態碼添加另外的錯誤頁面。
1
2
3
4
|
<
error-page
>
<
error-softwaresecurity
>500</
error-softwaresecurity
>
<
location
>/path/to/error.jsp</
location
>
</
error-page
>
|
另外,web.xml文件應該被配置以防止詳細的錯誤堆棧信息被顯示出來,我們可以通過配置<exception-type>來實現。因為Throwable是Java中所有Exception和Error的基類,下面的代碼片段將很好的確保堆棧信息不被服務器顯示。
1
2
3
4
|
<
error-page
>
<
exception-type
>java.lang.Throwable</
exception-type
>
<
location
>/path/to/error.jsp</
location
>
</
error-page
>
|
然而,如果你采用如下的處理方式,你依然會將堆棧信息展示出來:
<% try { String s = null; s.length(); } catch (Exception e) { // don't do this! e.printStackTrace(new PrintWriter(out)); } %>
這里請記住在合理配置了你的web.xml文件后,需要使用合理的日志記錄技巧。
(2)繞過認證和授權
下面的代碼片段展示了如何設置基於web的訪問控制以便所有在”安全”目錄中的一切只能被帶有”admin”角色的用戶訪問。
1
2
3
4
5
6
7
8
9
10
11
|
<
security-constraint
>
<
web-resource-collection
>
<
web-resource-name
>secure</
web-resource-name
>
<
url-pattern
>/secure/*</
url-pattern
>
<
http-method
>GET</
http-method
>
<
http-method
>POST</
http-method
>
</
web-resource-collection
>
<
auth-constraint
>
<
role-name
>admin</
role-name
>
</
auth-constraint
>
</
security-constraint
>
|
從常識觀點來看,指定了GET和POST的<http-method>元素限定了*只有*GET和POST請求是被允許的。事實上不是這樣,任意未列舉的HTTP方法實際上都是允許使用的,即采用其他的HTTP方法可以繞過認證和授權。Arshan Dabirsiaghi有一個非常好的論文總結了該問題並向你展示了如何使用上述配置中未列舉的任意的HTTP動詞(像HEAD)和完全假冒的動詞(像TEST或JUNK)來繞過web.xml中配置的認證和授權保護。
幸運的是,解決方案非常簡單。僅僅需要從web.xml文件中移除<http-method>元素即可。
(3)SSL未配置
在所有使用敏感數據的應用中,SSL都應該被配置以保護數據傳輸安全。當然你可以在web服務器上配置SSL,但是一旦你的應用服務器設置了合適的SSL key,那么在應用急啟用SSL是非常容易的。
1
2
3
4
5
6
|
<
security-constraint
>
...
<
user-data-constraint
>
<
transport-guarantee
>CONFIDENTIAL</
transport-guarantee
>
</
user-data-constraint
>
</
security-constraint
>
|
(4)未使用安全標示
很多web站點使用SSL進行認證,但是后面或者是阻止非SSL的的后續交互或者使得一部分網站內容仍然可以通過非SSL的訪問。這使得會話的cookie(也就是JSESSIONID)容易受到session劫持攻擊。要阻止它,cookie可以通過添加安全標志來創建,這確保了瀏覽器將不會在非SSL環境下傳遞cookie。
在Servlet規范的舊版本中,沒有標准的方式來將JSESSIONID定義為安全的。現在在Servlet3.0中,<cookie-config>元素可以用於確保這個。
1
2
3
4
5
|
<
session-config
>
<
cookie-config
>
<
secure
>true</
secure
>
</
cookie-config
>
</
session-config
>
|
(5)未使用HttpOnly標志
cookie可以使用HttpOnly標志創建,這將確保cookie不能被客戶端腳本訪問。這幫助減輕了一些常見的XSS攻擊。就像Security標志一樣,舊版本的Servlet規范沒有提供相應的支持。在Servlet3.0中可以如下的配置它:
1
2
3
4
5
|
<
session-config
>
<
cookie-config
>
<
http-only
>true</
http-only
>
</
cookie-config
>
</
session-config
>
|
除了Servlet3.0的這種新的標准的方式,舊版本的Tomcat允許在server.xml中使用供應商特定的useHttpOnly屬性來啟用它。該屬性在Tomcat5.5和6中默認是禁用的。在Tomcat7中,該屬性默認是啟用的。因此即使你在web.xml中將其設置為false,然后部署在tomcat7中,除非你修改了server.xml文件,否則你的JSESSIONID依然是HttpOnly的。
(6) 使用URL參數來跟蹤session
Servlet3.0規范中的<tracking-mode>允許你定義JSESSIONID是存儲在cookie中還是URL參數中。如果會話ID存儲在URL中,那么它可能會被無意的存儲在多個地方,包括瀏覽器歷史、代理服務器日志、引用日志和web日志等。暴露了會話ID使得網站被session劫持攻擊的幾率大增。然而,確保JSESSIONID被存儲在cookie中非常容易:
1
2
3
|
<
session-config
>
<
tracking-mode
>COOKIE</
tracking-mode
>
</
session-config
>
|
(7) 未設置會話超時時間
用戶喜歡長時間的會話因為他們很方便。黑客喜歡長時間的會話因為他們有足夠的時間來實施像session劫持攻擊等。安全和可用性總是會出現沖突。一旦你知道如何使得你的會話存活,你可以按如下方法來配置活動時間:
1
2
3
|
<
session-config
>
<
session-timeout
>15</
session-timeout
>
</
session-config
>
|
總結
構建和部署安全的應用需要從不同的受益人處獲取需求。環境和配置和編碼自身一樣重要。通過思考這些常見的安全錯誤配置,希望你可以創建更加安全的應用。