Tomcat / Java WebApps에서 HttpOnly 쿠키를 어떻게 구성합니까?
Tomcat / Java WebApps에서 HttpOnly 쿠키를 어떻게 구성합니까?
쿠키 보호에 대한 Jeff의 블로그 게시물을 읽은 후 : HttpOnly . 내 웹 응용 프로그램에서 HttpOnly 쿠키를 구현하고 싶습니다.
세션에 http 전용 쿠키를 사용하도록 바람둥이에게 어떻게 지시합니까?
httpOnly는 Tomcat 6.0.19 및 Tomcat 5.5.28부터 지원됩니다.
버그 44382에 대한 변경 로그 항목을 참조하십시오 .
버그 44382에 대한 마지막 주석은 "이것은 5.5.x에 적용되었으며 5.5.28 이후에 포함될 것입니다."라고 말합니다. 그러나 5.5.28이 릴리스 된 것으로 보이지 않습니다.
httpOnly 기능은 conf / context.xml의 모든 웹앱에 대해 활성화 할 수 있습니다 .
<Context useHttpOnly="true">
...
</Context>
내 해석은 위와 같은 방식으로 conf / server.xml 의 원하는 컨텍스트 항목에 설정하여 개별 컨텍스트에 대해서도 작동한다는 것 입니다.
업데이트 : 여기 JSESSIONID 항목은 이전 컨테이너에만 해당됩니다. <Tomcat 6.0.19 또는 <Tomcat 5.5.28 또는 HttpOnly JSESSIONID 쿠키를 구성 옵션으로 지원하지 않는 다른 컨테이너를 사용하지 않는 한 jt의 현재 허용되는 답변을 사용하십시오.
앱에서 쿠키를 설정할 때
response.setHeader( "Set-Cookie", "name=value; HttpOnly");
그러나 많은 웹앱에서 가장 중요한 쿠키는 컨테이너에서 자동으로 JSESSIONID 쿠키로 설정되는 세션 식별자입니다.
이 쿠키 만 사용하는 경우 ServletFilter를 작성하여 나가는 중에 쿠키를 다시 설정하여 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" );
}
그러나 이렇게하면 모든 쿠키를 덮어 쓰고이 필터에서 여기에 명시된 내용 만 설정합니다.
JSESSIONID 쿠키에 추가 쿠키를 사용하는 경우이 코드를 확장하여 필터의 모든 쿠키를 설정해야합니다. 이것은 쿠키가 여러 개인 경우 훌륭한 솔루션은 아니지만 JSESSIONID 전용 설정에 허용되는 빠른 수정일 수 있습니다.
시간이 지남에 따라 코드가 발전함에 따라이 필터를 잊어 버리고 코드의 다른 곳에 다른 쿠키를 설정하려고 할 때 당신을 기다리는 불쾌한 숨겨진 버그가 있다는 점에 유의하십시오. 물론 설정되지는 않습니다.
그래도 이것은 정말 해킹입니다. Tomcat을 사용하고 컴파일 할 수 있다면 HttpOnly 지원을 Tomcat에 패치하라는 Shabaz의 훌륭한 제안을 살펴보십시오.
https 세션에서 "; secure"쿠키 플래그를 덮어 쓰지 않도록주의하십시오. 이 플래그는 브라우저가 암호화되지 않은 http 연결을 통해 쿠키를 보내는 것을 방지하여 기본적으로 합법적 인 요청에 대해 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);
}
}
세션 쿠키의 경우 아직 Tomcat에서 지원되지 않는 것 같습니다. HTTPOnly 세션 쿠키 매개 변수에 대한 지원을 추가해야하는 버그 보고서를 참조하십시오 . 현재 다소 관련된 해결 방법은 여기 에서 찾을 수 있으며 기본적으로 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);
}
웹 서버가 tomcat 7.0+와 같은 Serlvet 3.0 사양을 지원하는 경우 다음과 같이 사용할 수 있습니다 web.xml
.
<session-config>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
</session-config>
문서에서 언급했듯이 :
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
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.
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)
.
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();
}
}
}
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