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

发布于 2024-07-04 02:16:57 字数 212 浏览 7 评论 0原文

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

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

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 http only cookies for sessions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

ヅ她的身影、若隐若现 2024-07-11 02:16:57

对于会话cookie,Tomcat 似乎还不支持。 请参阅错误报告需要添加对 HTTPOnly 会话 cookie 参数的支持。 目前,可以在 此处< /a>,这基本上可以归结为手动修补 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);
}

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);
}
傲世九天 2024-07-11 02:16:57

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

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

For cookies that I am explicitly setting, I switched to use SimpleCookie provided by Apache Shiro. It does not inherit from javax.servlet.http.Cookie so it takes a bit more juggling to get everything to work correctly however it does provide a property set HttpOnly and it works with Servlet 2.5.

For setting a cookie on a response, rather than doing response.addCookie(cookie) you need to do cookie.saveTo(request, response).

ら栖息 2024-07-11 02:16:57

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

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

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.

久伴你 2024-07-11 02:16:57

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

在应用程序中设置 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 中。

Update: The JSESSIONID stuff here is
only for older containers. Please use
jt's currently accepted answer unless
you are using < Tomcat 6.0.19 or < Tomcat
5.5.28 or another container that does not support HttpOnly JSESSIONID cookies as a config option.

When setting cookies in your app, use

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

However, in many webapps, the most important cookie is the session identifier, which is automatically set by the container as the JSESSIONID cookie.

If you only use this cookie, you can write a ServletFilter to re-set the cookies on the way out, forcing JSESSIONID to HttpOnly. The page at http://keepitlocked.net/archive/2007/11/05/java-and-httponly.aspx http://alexsmolen.com/blog/?p=16 suggests adding the following in a filter.

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

but note that this will overwrite all cookies and only set what you state here in this filter.

If you use additional cookies to the JSESSIONID cookie, then you'll need to extend this code to set all the cookies in the filter. This is not a great solution in the case of multiple-cookies, but is a perhaps an acceptable quick-fix for the JSESSIONID-only setup.

Please note that as your code evolves over time, there's a nasty hidden bug waiting for you when you forget about this filter and try and set another cookie somewhere else in your code. Of course, it won't get set.

This really is a hack though. If you do use Tomcat and can compile it, then take a look at Shabaz's excellent suggestion to patch HttpOnly support into Tomcat.

深巷少女 2024-07-11 02:16:57

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

请参阅 bug 44382 的 changelog 条目。

bug 44382 声明,“这已应用于 5.5.x 并将包含在5.5.28 起。” 不过5.5.28似乎还没有发布。

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

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

我的解释是,通过将其设置在所需的上下文 conf/server.xml 中的条目(与上面的方式相同)。

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).

魂ガ小子 2024-07-11 02:16:57

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

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);
    }
}
五里雾 2024-07-11 02:16:57

如果您的 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>

文档中所述:

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

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

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

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

偏爱自由 2024-07-11 02:16:57

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

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();
        }
    }
}
剧终人散尽 2024-07-11 02:16:57

我在 OWASP 中发现,

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

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

I Found in OWASP

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

this is also fix for "httponlycookies in config" security issue

一梦等七年七年为一梦 2024-07-11 02:16:57

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

Implementation: in Tomcat 7.x/8.x/9.x

Go to Tomcat >> conf folder
Open web.xml and add below in session-config section

    <cookie-config>
        <http-only>true</http-only>
        <secure>true</secure>
    </cookie-config>
戈亓 2024-07-11 02:16:57

从Java Enterprise Edition 6(JEE 6)开始,可以直接设置cookie:

    cookie.setHttpOnly(true);

Since Java Enterprise Edition 6 (JEE 6),you can set cookie directly:

    cookie.setHttpOnly(true);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文