Tomcat 7 sessionid cookie disable http-only and secure
cookie-httponly, cookies, httponly, session-cookies, tomcat7
Solution
If you read the code from tomcat you will find:
// Always set secure if the request is secure
if (scc.isSecure() || secure) {
cookie.setSecure(true);
}
So trying to deactivate Secure flag on JSESSIONID cookie with `sessionCookieConfig.setSecure(false);` in a listener or `<cookie-config><secure>false</secure></cookie-config>` in the web.xml WON'T WORK as Tomcat force the secure flag to true if the request is secure (ie came from an https url or the SSL port).
A solution is to use a request filter to modify the JSESSIONID cookie on the server response immediately after the session creation. This is my implementation (very basic):
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));
}
}
}
}
}
and in the 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>
Remember that enabling insecure cookies bypass an important https security! (I had to do that for a smooth transition from http to https)
Problem
I have a web application which is running on a Tomcat 7 server. The cookie with session id has by default the flags `HttpOnly` and `Secure`. I want to disable this flags for the `JSESSIONID` cookie. But it wont work. I have changed this in my `web.xml` file but it is not working. ``` <session-config> <session-timeout>20160</session-timeout> <cookie-config> <http-only>false</http-only> <secure>false</secure> </cookie-config> </session-config> ``` I know this is a security risk because a attacker is able to steal the cookie and hijack the session if he has found a xss vuln. The `JSESSIONID` cookie should be send with HTTP and HTTPS and with AJAX requests. Edit: I have successfuly disabled the `HttpOnly` flag by adding the following option to the `conf/context.xml` file: ``` <Context useHttpOnly="false"> .... </Context> ```