How do you configure HttpOnly cookies in tomcat / java webapps?

后端 未结 9 978
迷失自我
迷失自我 2020-11-27 10:47

After reading Jeff\'s blog post on Protecting Your Cookies: HttpOnly. I\'d like to implement HttpOnly cookies in my web application.

How do you tell tomcat to use ht

相关标签:
9条回答
  • 2020-11-27 11:00

    For session cookies it doesn't seem to be supported in Tomcat yet. See the bug report Need to add support for HTTPOnly session cookie parameter. A somewhat involved work-around for now can be found here, which basically boils down to manually patching Tomcat. Can't really find an easy way to do it at this moment at this point I'm affraid.

    To summarize the work-around, it involves downloading the 5.5 source, and then change the source in the following places:

    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);
    }
    
    0 讨论(0)
  • 2020-11-27 11:01

    httpOnly is supported as of Tomcat 6.0.19 and Tomcat 5.5.28.

    See the changelog entry for bug 44382.

    The last comment for bug 44382 states, "this has been applied to 5.5.x and will be included in 5.5.28 onwards." However, it does not appear that 5.5.28 has been released.

    The httpOnly functionality can be enabled for all webapps in conf/context.xml:

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

    My interpretation is that it also works for an individual context by setting it on the desired Context entry in conf/server.xml (in the same manner as above).

    0 讨论(0)
  • 2020-11-27 11:01

    If your web server supports Serlvet 3.0 spec, like tomcat 7.0+, you can use below in web.xml as:

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

    As mentioned in docs:

    HttpOnly: Specifies whether any session tracking cookies created by this web application will be marked as HttpOnly

    Secure: Specifies whether any session tracking cookies created by this web application will be marked as secure even if the request that initiated the corresponding session is using plain HTTP instead of HTTPS

    Please refer to how to set httponly and session cookie for java web application

    0 讨论(0)
  • 2020-11-27 11:12

    In Tomcat6, You can conditionally enable from your HTTP Listener Class:

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

    Using this class

    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();
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 11:21

    Please be careful not to overwrite the ";secure" cookie flag in https-sessions. This flag prevents the browser from sending the cookie over an unencrypted http connection, basically rendering the use of https for legit requests pointless.

    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);
        }
    }
    
    0 讨论(0)
  • 2020-11-27 11:23

    also it should be noted that turning on HttpOnly will break applets that require stateful access back to the jvm.

    the Applet http requests will not use the jsessionid cookie and may get assigned to a different tomcat.

    0 讨论(0)
提交回复
热议问题