【问题标题】:How do you configure HttpOnly cookies in tomcat / java webapps?如何在 tomcat/java webapps 中配置 HttpOnly cookie?
【发布时间】:2010-09-07 04:46:49
【问题描述】:

在阅读了 Jeff 在 Protecting Your Cookies: HttpOnly 上的博文后。我想在我的网络应用程序中实现 HttpOnly cookie。

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

【问题讨论】:

    标签: java security cookies xss httponly


    【解决方案1】:

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

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

    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);
    }
    

    【讨论】:

      【解决方案2】:

      更新:这里的 JSESSIONID 内容是 仅适用于较旧的容器。请用 jt 目前接受的答案,除非 您正在使用

      在您的应用中设置 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 中。

      【讨论】:

      • 此代码删除了 ;Secure 标志,从而使 https 的使用毫无意义。
      • 在 Servlet 3.0 投诉应用程序服务器中,我可以通过将以下内容添加到 web.xml 来设置会话 cookie (JSESSIONID) 的 HttpOnly 和安全标志: true true
      • @RogerJin 请将此作为新答案发布,这个已有 6 年历史的答案越来越过时了。
      • 小心 setHeader 因为它会删除所有以前的同名标题。例如,它可以在您设置自定义 cookie 时删除 JSESSIONID cookie。而是将 response.addHeader() 用于自定义 cookie
      【解决方案3】:

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

      请参阅changelog 条目以了解错误 44382。

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

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

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

      我的解释是,通过将其设置在 conf/server.xml 中所需的 Context 条目上,它也适用于单个上下文(方法同上)。

      【讨论】:

      • 我正在运行 Tomcat 5.5.36。这个 useHttpOnly 属性似乎只适用于 JSESSIONID cookie。我在所有上下文中都添加了这个标志,以确保所有 cookie 都将添加到末尾的“; HttpOnly”。但是,只有 JSESSIONID 受到以下影响:Set-Cookie=JSESSIONID=25E8F...;路径=/自定义路径; HttpOnly mycustomcookie1=xxxxxxx;路径=/mycustomcookie2=1351101062602;路径=/ mycustomcookie3=0;路径=/ mycustomcookie4=1;路径=/;安全 mycustomcookie5=4000;过期=星期六,2022 年 10 月 22 日 17:51:02 GMT; Path=/ 还有什么我做错了吗?
      • 此文档似乎表明 useHttpOnly 标志仅与会话 id cookie 相关:tomcat.apache.org/tomcat-5.5-doc/config/… 我认为这是旨在保护会话 cookie 的权宜之计。将 cookie 标记为 HttpOnly 的功能直到 3.0(Tomcat 7 涵盖)才成为 Servlet 规范的一部分:today.java.net/pub/a/today/2008/10/14/…
      【解决方案4】:

      请注意不要覆盖 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);
          }
      }
      

      【讨论】:

      • 请注意,使用request.isSecure() 并不总是准确的。考虑在 LB 后面执行 SSL 加速的负载平衡节点。从浏览器到负载均衡器的请求将通过 HTTPS 发送,而负载均衡器和实际服务器之间的请求将通过纯 HTTP 发送。这将导致request.isSecure() 成为false,而浏览器正在使用 SSL。
      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

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

        要在响应中设置 cookie,而不是执行 response.addCookie(cookie),您需要执行 cookie.saveTo(request, response)

        【讨论】:

          【解决方案7】:

          如果您的网络服务器支持 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:指定是否有任何会话跟踪cookies创建 此 Web 应用程序将被标记为 HttpOnly

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

          请参考how to set httponly and session cookie for java web application

          【讨论】:

            【解决方案8】:

            在 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();
                    }
                }
            }
            

            【讨论】:

              【解决方案9】:

              我在OWASP找到

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

              这也是“httponlycookies in config”安全问题的修复

              【讨论】:

                【解决方案10】:

                实现:在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>
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2012-10-14
                  • 1970-01-01
                  • 2020-03-19
                  • 2011-04-01
                  • 2011-02-28
                  • 1970-01-01
                  • 2014-08-24
                  • 2017-01-30
                  相关资源
                  最近更新 更多