The context.xml changes mentioned by javagc will only reconfigure your session cookie.
To change all of your cookies, you have 2 options:
Option 1) Update your application code to add cookies using a more secure method. Example: https://stackoverflow.com/a/30488471/95674
Option 2) You can configure a servlet filter to change ALL (other) cookies coming through the system. Add these 2 classes into the appropriate package in your WAR. Then update your web.xml as detailed below.
There is a simpler example of Option 2 listed on the OWASP site, if you are willing to add a dependency on the OWASP libraries. That is located here: https://www.owasp.org/index.php/HttpOnly#Using_Java_to_Set_HttpOnly
Response Wrapper
This adds the http only flag to all cookies on the wrapped response.
public class HttpOnlyResponseWrapper extends HttpServletResponseWrapper {
public HttpOnlyResponseWrapper(HttpServletResponse res) {
super(res);
}
public void addCookie(Cookie cookie) {
StringBuilder header = new StringBuilder();
if ((cookie.getName() != null) && (!cookie.getName().equals(""))) {
header.append(cookie.getName());
}
if (cookie.getValue() != null) {
// Empty values allowed for deleting cookie
header.append("=" + cookie.getValue());
}
if (cookie.getVersion() == 1) {
header.append(";Version=1");
if (cookie.getComment() != null) {
header.append(";Comment=\"" + cookie.getComment() + "\"");
}
if (cookie.getMaxAge() > -1) {
header.append(";Max-Age=" + cookie.getMaxAge());
}
} else {
if (cookie.getMaxAge() > -1) {
Date now = new Date();
now.setTime(now.getTime() + (1000L * cookie.getMaxAge()));
SimpleDateFormat cookieFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss zzz");
header.append(";Expires=" + cookieFormat.format(now));
}
}
if (cookie.getDomain() != null) {
header.append(";Domain=" + cookie.getDomain());
}
if (cookie.getPath() != null) {
header.append(";Path=" + cookie.getPath());
}
if (cookie.getSecure()) {
header.append(";Secure");
}
header.append(";httpOnly");
addHeader("Set-Cookie", header.toString());
}
}
Filter
This Filter wraps configured responses in the above wrapper.
package yourpackage;
@WebFilter(filterName = "HttpOnlyFilter", urlPatterns = {"/*"})
public class HttpOnlyFilter implements Filter {
private FilterConfig config;
@Override
public void destroy() {
this.config = null;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpOnlyResponseWrapper hres = new HttpOnlyResponseWrapper((HttpServletResponse)res);
chain.doFilter(req, hres);
}
public FilterConfig getFilterConfig() {
return this.config;
}
@Override
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
}
Adapted (WARNING: NOT an exact copy!) from source: http://sylvanvonstuppe.blogspot.com/2007/07/servlet-filter-for-httponly.html
web.xml
One last detail: ONLY IF you have annotation scanning turned OFF in your system like this:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
version="2.5" ***metadata-complete="true"***>
</web-app>
Then you will need to manually configure the above Filter in your web.xml file, like this:
<filter>
<filter-name>HttpOnlyFilter
<filter-class>yourpackage.HttpOnlyFilter
</filter>
<filter-mapping>
<filter-name>HttpOnlyFilter
<url-pattern>/*
</filter-mapping>
If your app scans annotations (which is the default), the web.xml part is not necessary.