如何在tomcat / java webapps中配置HttpOnly cookie?

时间:2008-08-28 21:09:31

标签: java security cookies xss httponly

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

您如何告诉tomcat仅使用http http会话?

10 个答案:

答案 0 :(得分:61)

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

有关错误44382,请参阅changelog条目。

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

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

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

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

答案 1 :(得分:19)

  

更新:这里的JSESSIONID内容是   仅适用于旧容器。请用   jt目前接受的答案除非   你正在使用&lt; Tomcat 6.0.19或&lt; Tomcat的   5.5.28或其他不支持HttpOnly JSESSIONID cookie作为配置选项的容器。

在应用中设置Cookie时,请使用

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

但是,在许多webapps中,最重要的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时,会有一个令人讨厌的隐藏错误等着您。当然,它不会被设定。

这真的是一个黑客。如果您确实使用Tomcat并且可以编译它,那么请看看Shabaz的优秀建议,即将HttpOnly支持修补到Tomcat中。

答案 2 :(得分: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);
    }
}

答案 3 :(得分:9)

对于会话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);
}

答案 4 :(得分:8)

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

     

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

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

答案 5 :(得分:2)

还应该注意的是,打开HttpOnly会破坏需要有状态访问jlet的applet。

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

答案 6 :(得分:2)

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

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

答案 7 :(得分: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();
        }
    }
}

答案 8 :(得分:0)

我在OWASP找到

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

这也解决了“配置中的httponlycookies”安全问题

答案 9 :(得分: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>