Tomcat 7 sessionid cookie禁用http-only和secure

时间:2013-08-01 10:10:12

标签: cookies tomcat7 session-cookies httponly cookie-httponly

我有一个在Tomcat 7服务器上运行的Web应用程序。具有会话ID的cookie默认具有标志HttpOnlySecure。我想为JSESSIONID cookie禁用此标志。但它不会工作。我已经在我的web.xml文件中对此进行了更改,但它无效。

<session-config>
    <session-timeout>20160</session-timeout>
    <cookie-config>
        <http-only>false</http-only>
        <secure>false</secure>
    </cookie-config>
</session-config>

我知道这是一个安全风险,因为攻击者能够窃取cookie并劫持会话,如果他找到了xss vuln。

JSESSIONID cookie应该使用HTTP和HTTPS以及AJAX请求发送。

修改

我已成功通过在HttpOnly文件中添加以下选项来禁用conf/context.xml标记:

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

3 个答案:

答案 0 :(得分:1)

我没有在Tomcat中找到解决方案,但是如果你使用apache作为反向代理,你可以这样做:

Header edit* Set-Cookie "(JSESSIONID=.*)(; Secure)" "$1"

使用mod_headers,它会在返回途中删除标题以删除安全标记。不漂亮,但如果这很重要,那就有效。

答案 1 :(得分:1)

如果您阅读code from tomcat,您会发现:

// Always set secure if the request is secure
if (scc.isSecure() || secure) {
    cookie.setSecure(true);
}

因此,尝试在侦听器中使用sessionCookieConfig.setSecure(false);或在web.xml中<cookie-config><secure>false</secure></cookie-config>停用JSESSIONID cookie上的安全标志将无效,因为如果请求是安全的,Tomcat会将安全标志强制为true(即来自https网址或SSL端口。)

解决方案是使用请求过滤器在会话创建后立即修改服务器响应上的JSESSIONID cookie。 这是我的实现(非常基础):

public class DisableSecureCookieFilter implements javax.servlet.Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if(request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
            request = new ForceUnsecureSessionCookieRequestWrapper((HttpServletRequest) request, (HttpServletResponse) response);
        }

        chain.doFilter(request, response);
    }

    @Override
    public void destroy() { }

    public static class ForceUnsecureSessionCookieRequestWrapper extends HttpServletRequestWrapper {
        HttpServletResponse response;

        public ForceUnsecureSessionCookieRequestWrapper(HttpServletRequest request, HttpServletResponse response) {
            super(request);
            this.response = response;
        }

        @Override
        public HttpSession getSession(boolean create) {
            if(create) {
                HttpSession session = super.getSession(create);
                updateCookie(response.getHeaders("Set-Cookie"));
                return session;
            }
            return super.getSession(create);
        }

        @Override
        public HttpSession getSession() {
            HttpSession session = super.getSession();
            if(session != null) {
                updateCookie(response.getHeaders("Set-Cookie"));
            }

            return session;
        }

        protected void updateCookie(Collection<String> cookiesAfterCreateSession) {
            if(cookiesAfterCreateSession != null && !response.isCommitted()) {
                // search if a cookie JSESSIONID Secure exists
                Optional<String> cookieJSessionId = cookiesAfterCreateSession.stream()
                                                        .filter(cookie -> cookie.startsWith("JSESSIONID") && cookie.contains("Secure"))
                                                        .findAny();
                if(cookieJSessionId.isPresent()) {
                    // remove all Set-Cookie and add the unsecure version of the JSessionId Cookie
                    response.setHeader("Set-Cookie", cookieJSessionId.get().replace("Secure", ""));

                    // re-add all other Cookies
                    cookiesAfterCreateSession.stream()
                            .filter(cookie -> !cookie.startsWith("JSESSIONID"))
                            .forEach(cookie -> response.addHeader("Set-Cookie", cookie));
                }
            }
        }
    }

}

并在web.xml中:

<filter>
    <filter-name>disableSecureCookieFilter</filter-name>
    <filter-class>com.xxxx.security.DisableSecureCookieFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>disableSecureCookieFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

请记住,启用不安全的Cookie会绕过重要的https安全性!(我必须这样做才能从http平滑过渡到https)

答案 2 :(得分:-1)

除了上面针对Apache的George Powell的解决方案,如果您使用的是IIS,可以按如下方式解决:

  1. 安装IIS URL重写模块
  2. 将以下内容添加到您的web.config
  3. &#13;
    &#13;
    <rewrite>
      <outboundRules>
        <rule name="RemoveSecureJessionID">
          <match serverVariable="RESPONSE_Set-Cookie" pattern="^(.*JSESSIONID.*)Secure;(.*)$" />
          <action type="Rewrite" value="{R:1}{R:2}" />
        </rule>
      </outboundRules>
    </rewrite>
    &#13;
    &#13;
    &#13;

    此解决方案来自Pete Freitag's blog

    如上所述,自最近的Chrome更新(2017年1月)以来,这已经成为一个问题。