如何防止tomcat会话劫持? [英] How to prevent tomcat session hijacking?

查看:88
本文介绍了如何防止tomcat会话劫持?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的web.xml中,我为某些资源定义了用户数据约束:

In my web.xml I've defined a user-data-constraint for some resources:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Personal Area</web-resource-name>
        <url-pattern>/personal/*</url-pattern>
    </web-resource-collection>
    <web-resource-collection>
        <web-resource-name>User Area</web-resource-name>
        <url-pattern>/user/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>




  1. 当我用http加载页面时我得到了我的JSESSIONID ID1在我的cookie中。

  2. 当我更改为context / user / sample.faces时,Tomcat会将302重定向到HTTPS。但是我的JSESSIONID仍然是ID1。

我认为这是一个漏洞?或者是我的配置错误?

I think this is a vulnerability? Or is it my configuration mistake?

我看到的问题如下:在使用cookie ID1浏览HTTP时,有一个攻击者正在侦听我的网络流量。他窃取我的cookie ID1。现在我切换到HTTPS,我的cookie仍然是ID1。我登录然后攻击者能够接管我的会话,因为他知道我的cookie ...

The problem I see is the following: While browsing over HTTP with cookie ID1 there is an attacker who is listening to my network traffic. He "steals" my cookie ID1. Now I switch to HTTPS and my cookie is still ID1. I login. The attacker is then able to taker over my session because he knows my cookie...

推荐答案

如果它是Tomcat的最新版本,你可能没有问题。但是,这取决于您检查与会话关联的SSL ID。这可以使用代码,例如

If it's a recent version of Tomcat, you may not have a problem. However, this depends on your checking the SSL ID associated with the session. This is available using code such as

String sslId = (String) req.getAttribute("javax.servlet.request.ssl_session");

(请注意,属性键将来可能会更改为 javax.servlet .request.ssl_session _id - 作为Servlet 3.0规范的一部分。)

(Note that the attribute key may change in the future to javax.servlet.request.ssl_session_id - as part of the Servlet 3.0 spec).

我使用以下 doGet 方法设置了一个servlet:

I set up a servlet with the following doGet method:

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 Headers扩展调用了一个合适的不受保护的URL,获取会话cookie。这是我导航到

I then invoked a suitable unprotected URL using Firefox and the Live HTTP Headers extension, to get the session cookie. This was the response sent when I navigated to

http://localhost:8080/EchoWeb/unprotected

(我的web.xml与你的一样,只保护/ user / *和/ personal / *):

(my web.xml, like yours, only protects /user/* and /personal/*):


URI: /EchoWeb/unprotected
SID: 9ACCD06B69CA365EFD8C10816ADD8D71
SSLID: null
Info: unprotected: 1254034761932
Secret: null
Date: 27/09/09 07:59

接下来,我尝试访问受保护的URL

Next, I tried to access a protected URL

http://localhost:8080/EchoWeb/personal/protected

并且,正如预期的那样,我被重定向到

and, as expected, I got redirected to

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欺骗服务器。

Notice that the cookie/session ID is the same, but we now have a new SSLID. Now, let's try to spoof the server using the session cookie.

我设置了一个Python脚本, spoof.py

I set up a Python script, 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。这是我两次运行恶搞脚本时的响应:

Now, you don't need to know Python, particularly - I'm just trying to send an HTTP request to a (different) protected resource with the same session ID in the Cookie. Here's the response when I ran my spoof script twice:


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选项卡,这里是响应:

Notice in the above responses that the session data (a value with a timestamp of 1254034761932) which was set in the first, unprotected request, has been sent throughout, because Tomcat is using the same session because the session ID is the same. This is of course not secure. However, note that the SSL IDs were different each time and if you use those to key into your session data (e.g. as shown), you should be safe. If I refresh my Firefox tab, here's the response:


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会话不同。

Notice that the SSLID is the same as for the earlier Firefox request. So, the server can tell the sessions apart using the SSL ID value. Notice particularly that the "protected data" is the same for each request made from the Firefox session, but different for each of the spoofed sessions and also different from the Firefox session.

这篇关于如何防止tomcat会话劫持?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆