阅读Jeff关于保护您的Cookie的博客文章:HttpOnly。我想在我的Web应用程序中实现HttpOnly cookie。
您如何告诉tomcat在会话中仅使用http cookie?
阅读Jeff关于保护您的Cookie的博客文章:HttpOnly。我想在我的Web应用程序中实现HttpOnly cookie。
您如何告诉tomcat在会话中仅使用http cookie?
Answers:
更新:这里的JSESSIONID内容仅适用于较旧的容器。除非您使用<Tomcat 6.0.19或<Tomcat 5.5.28或其他不支持HttpOnly JSESSIONID cookie的容器作为配置选项,否则请使用jt当前接受的答案。
在您的应用中设置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时,会有一个令人讨厌的隐藏错误等待着您。当然,它不会被设置。
这确实是一个hack。如果您确实使用了Tomcat并且可以对其进行编译,那么请看一下Shabaz关于将HttpOnly支持修补到Tomcat中的出色建议。
请注意不要覆盖https-sessions中的“; secure” cookie标志。此标志可防止浏览器通过未加密的http连接发送cookie,从而使对合法请求的HTTP使用变得毫无意义。
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);
}
}
request.isSecure()
并不总是准确的。考虑在LB后面执行SSL加速的负载平衡节点。从浏览器到负载均衡器的请求将通过HTTPS发出,而负载均衡器与实际服务器之间的请求将通过纯HTTP发出。这将导致request.isSecure()
是false
,当浏览器使用SSL。
如果您的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:指定是否将此Web应用程序创建的任何会话跟踪cookie都标记为HttpOnly。
安全:指定是否将由此Web应用程序创建的任何会话跟踪cookie标记为安全,即使发起相应会话的请求使用的是纯HTTP而不是HTTPS
对于会话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);
}
对于我明确设置的cookie,我切换为使用Apache Shiro提供的SimpleCookie。它没有继承自javax.servlet.http.Cookie,因此要使一切正常工作还需要花费一些时间,但是它确实提供了HttpOnly属性集,并且可以与Servlet 2.5一起使用。
要在响应上设置Cookie,而response.addCookie(cookie)
无需这样做cookie.saveTo(request, response)
。
我在OWASP中找到
<session-config>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
</session-config>
这也解决了“配置中的httponlycookies”安全问题
在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();
}
}
}
Set-Cookie=
JSESSIONID = 25E8F ...; 路径= / custompath; HttpOnly mycustomcookie1 = xxxxxxx; 路径= / mycustomcookie2 = 1351101062602; 路径= / mycustomcookie3 = 0; 路径= / mycustomcookie4 = 1; 路径= /; 安全mycustomcookie5 = 4000; 过期时间为2022年10月22日星期六17:51:02 GMT;路径= /我还有其他地方做错了吗?