如果它是最新版本的Tomcat,則可能沒有問題。但是,這取決於您檢查與會話關聯的SSL ID。這是可使用的代碼如
String sslId = (String) req.getAttribute("javax.servlet.request.ssl_session");
(請注意,屬性關鍵可能在未來改變javax.servlet.request.ssl_session
_id
- 作爲servlet 3.0規範的一部分)。
我成立了一個servlet用以下方法doGet
:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(true);
String sid = session.getId();
String sslId = (String) request.getAttribute(
"javax.servlet.request.ssl_session");
String uri = request.getRequestURI();
OutputStream out = response.getOutputStream();
PrintWriter pw = new PrintWriter(out);
HashMap<String, Object> secrets;
Object secret = null;
Object notSecret;
Date d = new Date();
notSecret = session.getAttribute("unprotected");
if (notSecret == null) {
notSecret = "unprotected: " + d.getTime();
session.setAttribute("unprotected", notSecret);
}
secrets = (HashMap<String, Object>) session.getAttribute("protected");
if (secrets == null) {
secrets = new HashMap<String, Object>();
session.setAttribute("protected", secrets);
}
if (sslId != null) {
if (secrets.containsKey(sslId))
secret = secrets.get(sslId);
else {
secret = "protected: " + d.getTime();
secrets.put(sslId, secret);
}
}
response.setContentType("text/plain");
pw.println(MessageFormat.format("URI: {0}", new Object[] { uri }));
pw.println(MessageFormat.format("SID: {0}", new Object[] { sid }));
pw.println(MessageFormat.format("SSLID: {0}", new Object[] { sslId }));
pw.println(MessageFormat.format("Info: {0}", new Object[] { notSecret }));
pw.println(MessageFormat.format("Secret: {0}", new Object[] { secret }));
pw.println(MessageFormat.format("Date: {0}", new Object[] { d }));
pw.close();
}
我然後調用使用Firefox和Live HTTP頭延伸,以獲得會話cookie合適的未受保護的URL。這是當我瀏覽到
http://localhost:8080/EchoWeb/unprotected
發送的響應(我的web.xml中,像你這樣,不僅保護/用戶/ *和/個人/ *):
URI: /EchoWeb/unprotected
SID: 9ACCD06B69CA365EFD8C10816ADD8D71
SSLID: null
Info: unprotected: 1254034761932
Secret: null
Date: 27/09/09 07:59
接下來,我試着訪問受保護的URL
http://localhost:8080/EchoWeb/personal/protected
和,一如預期,我被重定向到
https://localhost:8443/EchoWeb/personal/protected
,反應也
URI: /EchoWeb/personal/protected
SID: 9ACCD06B69CA365EFD8C10816ADD8D71
SSLID: 4abf0d67549489648e7a3cd9292b671ddb9dd844b9dba682ab3f381b462d1ad1
Info: unprotected: 1254034761932
Secret: protected: 1254034791333
Date: 27/09/09 07:59
注意,該cookie /會話ID是一樣的,但我們現在有一個新的SSLID。現在,讓我們嘗試使用會話cookie來欺騙服務器。
我成立了一個Python腳本,spoof.py
:
import urllib2
url = "https://localhost:8443/EchoWeb/personal/protected"
headers = {
'Host': 'localhost:8080',
'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-gb,en;q=0.5',
'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'Cookie' : 'JSESSIONID=9ACCD06B69CA365EFD8C10816ADD8D71'
}
req = urllib2.Request(url, None, headers)
response = urllib2.urlopen(req)
print response.read()
現在,你不需要知道Python的,特別是 - 我只是試圖發送一個HTTP請求(不同的)保護的資源在Cookie中具有相同的會話ID。這裏的響應,當我跑我的惡搞腳本兩次:在上面的反應
C:\temp>spoof
URI: /EchoWeb/personal/protected
SID: 9ACCD06B69CA365EFD8C10816ADD8D71
SSLID: 4abf0eafb4ffa30b6579cf189c402a8411294201e2df94b33a48ae7484f22854
Info: unprotected: 1254034761932
Secret: protected: 1254035119303
Date: 27/09/09 08:05
C:\temp>spoof
URI: /EchoWeb/personal/protected
SID: 9ACCD06B69CA365EFD8C10816ADD8D71
SSLID: 4abf0eb184cb380ce69cce28beb01665724c016903650539d095c671d98f1de3
Info: unprotected: 1254034761932
Secret: protected: 1254035122004
Date: 27/09/09 08:05
注意,會話數據,在第一,未受保護的要求設置(與1254034761932
時間戳值),目前已在發,因爲Tomcat正在使用相同的會話,因爲會話ID是相同的。這當然是不安全。但是,請注意,SSL ID 每次都是不同的,如果您使用這些鍵入會話數據(例如,如圖所示),則應該是安全的。如果我刷新我的Firefox標籤,這裏的響應:
URI: /EchoWeb/personal/protected
SID: 9ACCD06B69CA365EFD8C10816ADD8D71
SSLID: 4abf0d67549489648e7a3cd9292b671ddb9dd844b9dba682ab3f381b462d1ad1
Info: unprotected: 1254034761932
Secret: protected: 1254034791333
Date: 27/09/09 08:05
注意,SSLID是相同作爲較早的Firefox請求。因此,服務器可以使用SSL ID值區分會話。特別要注意的是,對於每個來自Firefox會話的請求,「受保護的數據」都是相同的,但對於每個欺騙會話而言,不同,也不同於Firefox會話。
重新評論:SSLID相同的原因是會話是一樣的(畢竟我只是單擊了Firefox中的刷新)。你可以在會話管理中使用這個事實。至於SSLID是如何構建的 - 它不包含在servlet規範中,因此每個供應商都可以使用自己的機制。我希望你必須檢查Tomcat的來源。無論如何,你不應該依賴任何具體的實現 - 就像你使用JSESSIONID一樣使用它 - 作爲一個不透明的值。 – 2009-09-28 15:47:53