77

在阅读了 Jeff 关于保护您的 Cookie:HttpOnly的博文后。我想在我的 Web 应用程序中实现 HttpOnly cookie。

你如何告诉 tomcat 只使用 http cookie 进行会话?

4

10 回答 10

66

从 Tomcat 6.0.19 和 Tomcat 5.5.28 开始支持 httpOnly。

请参阅错误 44382 的更改日志条目。

错误44382的最后一条评论指出,“这已应用于 5.5.x 并将包含在 5.5.28 及以后的版本中。” 但是,似乎没有发布 5.5.28。

可以为conf/context.xml中的所有 webapps 启用 httpOnly 功能:

<Context useHttpOnly="true">
...
</Context>

我的解释是,它也适用于单个上下文,方法是在conf/server.xml中的所需上下文条目上设置它(以与上述相同的方式)。

于 2009-07-06T16:46:12.847 回答
20

更新:这里的 JSESSIONID 内容仅适用于较旧的容器。请使用 jt 当前接受的答案,除非您使用 < Tomcat 6.0.19 或 < Tomcat 5.5.28 或其他不支持 HttpOnly JSESSIONID cookie 作为配置选项的容器。

在您的应用程序中设置 cookie 时,请使用

response.setHeader( "Set-Cookie", "name=value; HttpOnly");

然而,在许多 webapp 中,最重要的 cookie 是会话标识符,它由容器自动设置为 JSESSIONID cookie。

如果你只使用这个cookie,你可以写一个ServletFilter在退出的时候重新设置cookie,强制JSESSIONID为HttpOnly。http://keepitlocked.net/archive/2007/11/05/java-and-httponly.aspx http://alexsmolen.com/blog/?p=16的页面建议在过滤器中添加以下内容。

if (response.containsHeader( "SET-COOKIE" )) {
  String sessionid = request.getSession().getId();
  response.setHeader( "SET-COOKIE", "JSESSIONID=" + sessionid 
                      + ";Path=/<whatever>; Secure; HttpOnly" );
} 

但请注意,这将覆盖所有 cookie,并且仅在此过滤器中设置您在此处声明的内容。

如果您对 JSESSIONID cookie 使用其他 cookie,则需要扩展此代码以在过滤器中设置所有 cookie。对于多个 cookie,这不是一个很好的解决方案,但对于仅 JSESSIONID 的设置来说,这可能是一个可以接受的快速修复。

请注意,随着您的代码随着时间的推移而发展,当您忘记此过滤器并尝试在代码中的其他位置设置另一个 cookie 时,会有一个令人讨厌的隐藏错误在等着您。当然,它不会被设置。

不过,这确实是一个hack。如果您确实使用 Tomcat 并且可以编译它,那么请查看 Shabaz 的出色建议,将 HttpOnly 支持修补到 Tomcat 中。

于 2008-08-28T21:37:36.270 回答
14

请注意不要覆盖 https-sessions 中的“;secure” cookie 标志。此标志可防止浏览器通过未加密的 http 连接发送 cookie,基本上使使用 https 进行合法请求毫无意义。

private void rewriteCookieToHeader(HttpServletRequest request, HttpServletResponse response) {
    if (response.containsHeader("SET-COOKIE")) {
        String sessionid = request.getSession().getId();
        String contextPath = request.getContextPath();
        String secure = "";
        if (request.isSecure()) {
            secure = "; Secure"; 
        }
        response.setHeader("SET-COOKIE", "JSESSIONID=" + sessionid
                         + "; Path=" + contextPath + "; HttpOnly" + secure);
    }
}
于 2009-09-23T10:04:59.587 回答
13

如果你的网络服务器支持 Serlvet 3.0 规范,比如 tomcat 7.0+,你可以在下面使用web.xml

<session-config>
  <cookie-config>
     <http-only>true</http-only>        
     <secure>true</secure>        
  </cookie-config>
</session-config>

如文档中所述:

HttpOnly:指定此 Web 应用程序创建的任何会话跟踪 cookie 是否将被标记为 HttpOnly

Secure:指定此 Web 应用程序创建的任何会话跟踪 cookie 是否将被标记为安全,即使启动相应会话的请求使用纯 HTTP 而不是 HTTPS

请参考如何为 java web 应用程序设置 httponly 和 session cookie

于 2015-06-23T07:04:45.613 回答
10

对于会话 cookie,Tomcat 似乎还不支持它。请参阅错误报告需要添加对 HTTPOnly 会话 cookie 参数的支持。现在可以在这里找到一个有点复杂的解决方法,基本上可以归结为手动修补 Tomcat。在这一点上,我真的找不到一种简单的方法来做到这一点,我很害怕。

总结一下解决方法,它涉及下载 5.5,然后在以下位置更改源:

org.apache.catalina.connector.Request.java

//this is what needs to be changed
//response.addCookieInternal(cookie);

//this is whats new
response.addCookieInternal(cookie, true);
}

org.apache.catalina.connectorResponse.addCookieInternal

public void addCookieInternal(final Cookie cookie) {
addCookieInternal(cookie, false);
}

public void addCookieInternal(final Cookie cookie, boolean HTTPOnly) {

if (isCommitted())
return;

final StringBuffer sb = new StringBuffer();
//web application code can receive a IllegalArgumentException
//from the appendCookieValue invokation
if (SecurityUtil.isPackageProtectionEnabled()) {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run(){
ServerCookie.appendCookieValue
(sb, cookie.getVersion(), cookie.getName(),
cookie.getValue(), cookie.getPath(),
cookie.getDomain(), cookie.getComment(),
cookie.getMaxAge(), cookie.getSecure());
return null;
}
});
} else {
ServerCookie.appendCookieValue
(sb, cookie.getVersion(), cookie.getName(), cookie.getValue(),
cookie.getPath(), cookie.getDomain(), cookie.getComment(),
cookie.getMaxAge(), cookie.getSecure());
}
//of course, we really need to modify ServerCookie
//but this is the general idea
if (HTTPOnly) {
sb.append("; HttpOnly");
}

//if we reached here, no exception, cookie is valid
// the header name is Set-Cookie for both "old" and v.1 ( RFC2109 )
// RFC2965 is not supported by browsers and the Servlet spec
// asks for 2109.
addHeader("Set-Cookie", sb.toString());

cookies.add(cookie);
}
于 2008-08-28T21:36:07.973 回答
2

还应该注意的是,打开 HttpOnly 会破坏需要状态访问回 jvm 的小程序。

Applet http 请求不会使用 jsessionid cookie,可能会被分配给不同的 tomcat。

于 2010-08-18T20:33:57.353 回答
2

对于我明确设置的 cookie,我转而使用Apache Shiro提供的SimpleCookie。它不是从 javax.servlet.http.Cookie 继承的,因此需要更多的时间才能让一切正常工作,但是它确实提供了一个属性集 HttpOnly 并且它适用于 Servlet 2.5。

为了在响应上设置 cookie,而不是response.addCookie(cookie)你需要做的cookie.saveTo(request, response).

于 2013-01-30T17:49:40.587 回答
2

我在OWASP中找到

<session-config>
  <cookie-config>
    <http-only>true</http-only>
  </cookie-config>
</session-config>

这也是“配置中的 httponlycookies”安全问题的修复

于 2018-12-06T13:00:02.393 回答
1

在 Tomcat6 中,您可以从 HTTP 侦听器类有条件地启用:

public void contextInitialized(ServletContextEvent event) {                 
   if (Boolean.getBoolean("HTTP_ONLY_SESSION")) HttpOnlyConfig.enable(event);
}

使用这个类

import java.lang.reflect.Field;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import org.apache.catalina.core.StandardContext;
public class HttpOnlyConfig
{
    public static void enable(ServletContextEvent event)
    {
        ServletContext servletContext = event.getServletContext();
        Field f;
        try
        { // WARNING TOMCAT6 SPECIFIC!!
            f = servletContext.getClass().getDeclaredField("context");
            f.setAccessible(true);
            org.apache.catalina.core.ApplicationContext ac = (org.apache.catalina.core.ApplicationContext) f.get(servletContext);
            f = ac.getClass().getDeclaredField("context");
            f.setAccessible(true);
            org.apache.catalina.core.StandardContext sc = (StandardContext) f.get(ac);
            sc.setUseHttpOnly(true);
        }
        catch (Exception e)
        {
            System.err.print("HttpOnlyConfig cant enable");
            e.printStackTrace();
        }
    }
}
于 2015-12-08T03:21:21.730 回答
0

实现:在Tomcat 7.x/8.x/9.x

转到 Tomcat >> conf 文件夹打开 web.xml 并在 session-config 部分添加以下内容

    <cookie-config>
        <http-only>true</http-only>
        <secure>true</secure>
    </cookie-config>
于 2021-05-29T05:54:51.450 回答