阅读 Jeff 的博客文章后 保护您的 Cookie:仅HTTP. 。我想在我的 Web 应用程序中实现 HttpOnly cookie。

如何告诉 tomcat 在会话中使用仅 http 的 cookie?

有帮助吗?

解决方案

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

请参阅 变更日志 bug 44382 的条目。

bug的最后评论 44382 各州:“这已应用于5.5.x,并将在5.5.28中包括在5.5.28中。”但是,似乎没有发布5.5.28。

可以为所有 web 应用程序启用 httpOnly 功能 conf/context.xml:

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

我的解释是,通过将其设置为所需的值,它也适用于个人上下文 语境 进入 conf/服务器.xml (与上面相同的方式)。

其他提示

更新:这里的JSessionId东西仅适用于较旧的容器。请使用JT当前接受的答案,除非您使用<tomcat 6.0.19或<tomcat 5.5.5.28或其他不支持HTTPonly JSessionId cookie作为配置选项的容器。

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

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

然而,在许多Web应用程序中,最重要的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 中。

请小心不要覆盖 https 会话中的“;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);
    }
}

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

如果您的Web服务器支持Serlvet 3.0规范,例如tomcat 7.0+,您可以在下面使用 web.xml 作为:

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

正如文档中提到的:

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

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

请参阅 如何为java web应用程序设置httponly和会话cookie

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

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

对于我明确设置的cookie,我改用 简单Cookie 由...提供 阿帕奇·希罗. 。它不是从 javax.servlet.http.Cookie 继承的,因此需要更多的处理才能让一切正常工作,但它确实提供了一个属性集 HttpOnly 并且可以与 Servlet 2.5 一起使用。

用于在响应上设置 cookie,而不是执行 response.addCookie(cookie) 你需要做 cookie.saveTo(request, response).

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

我发现于 OWASP

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top