Как настроить файлы cookie HttpOnly в tomcat / java webapps?

после прочтения сообщения в блоге Джеффа на Защита Ваших Файлов Cookie: HttpOnly. Я хотел бы реализовать файлы cookie HttpOnly в своем веб-приложении.

Как вы говорите tomcat использовать только файлы cookie http для сеансов?

8 ответов


httpOnly поддерживается с Tomcat 6.0.19 и Tomcat 5.5.28.

посмотреть изменений запись для ошибки 44382.

последний комментарий к bug 44382 заявляет: "Это было применено к 5.5.x и будет включен в раздел 5.5.28 и далее."Однако, как представляется, 5.5.28 не был выпущен.

функциональность httpOnly может быть включена для всех webapps в conf / context.в XML:

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

мой интерпретация заключается в том, что она также работает для отдельного контекста, устанавливая его на желаемом контекст вход в conf / server.в XML (аналогично выше).


Update: материал JSESSIONID здесь только для старых контейнеров. Пожалуйста, используйте JT в настоящее время принят ответ, если вы используете

при настройке cookies в вашем приложении используйте

response.setHeader( "Set-Cookie", "name=value; HttpOnly");

однако во многих webapps наиболее важным cookie является идентификатор сеанса, который автоматически устанавливается контейнер как файл cookie JSESSIONID.

Если вы используете только этот файл 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" );
} 

но обратите внимание, что это перезапишет все куки и только установить, что вы заявляете вот в этом фильтре.

Если вы используете дополнительные куки к куки JSESSIONID, то вам нужно будет расширить этот код, чтобы установить все куки в фильтре. Это не отличное решение в случае нескольких куки-файлов, но, возможно, приемлемое быстрое исправление для настройки только JSESSIONID.

обратите внимание, что по мере того, как ваш код развивается с течением времени, вас ждет неприятная скрытая ошибка, когда вы забудете об этом фильтре и попытаетесь установить другой файл cookie где-то еще ваш код. Конечно, он не будет установлен.

Это действительно Хак. Если вы используете Tomcat и можете его скомпилировать, посмотрите на отличное предложение Шабаза по исправлению поддержки HttpOnly в Tomcat.


пожалуйста, будьте осторожны, чтобы не перезаписать флаг ";secure" cookie в https-сеансах. Этот флаг запрещает браузеру отправлять файлы cookie через незашифрованное 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. См. отчет об ошибке необходимо добавить поддержку параметра cookie сеанса HTTPOnly. Несколько сложная работа-вокруг сейчас можно найти здесь, который в основном сводится к ручному исправлению Tomcat. Не могу найти простой способ сделать это в этот момент, в этот момент я боюсь.

чтобы суммировать работу, она включает в себя загрузку 5.5 источник, а затем измените источник в следующих местах:

org.апаш.Каталина.соединитель.Запрос.java

//this is what needs to be changed
//response.addCookieInternal(cookie);

//this is whats new
response.addCookieInternal(cookie, true);
}

org.апаш.Каталина.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);
}

Если ваш веб-сервер поддерживает спецификацию Serlvet 3.0, например tomcat 7.0+, вы можете использовать ниже в web.xml as:

<session-config>
  <cookie-config>
     <http-only>true</http-only>        
     <secure>true</secure>        
  </cookie-config>
</session-config>

как указано в документах:

HttpOnly: указывает, были ли созданы файлы cookie отслеживания сеансов это веб-приложение будет помечено как HttpOnly

безопасное: задает файлы cookie отслеживания сеансов, созданные этим веб-приложением будет отмечен как безопасный, даже если запрос инициатором соответствующий сеанс использует простой HTTP вместо HTTPS

пожалуйста, обратитесь к как установить httponly и cookie сеанса для веб-приложения java


также следует отметить, что включение HttpOnly нарушит апплеты, которые требуют доступа с сохранением состояния к jvm.

HTTP-запросы апплета не будут использовать cookie jsessionid и могут быть назначены другому tomcat.


для куки, которые я явно устанавливаю, я переключился на использование SimpleCookie предоставлен Apache Shiro. Он не наследуется от javax.сервлет.http.Cookie поэтому требуется немного больше жонглирования, чтобы все работало правильно, однако он предоставляет набор свойств HttpOnly и работает с сервлетом 2.5.

для установки cookie на ответ, а не делать response.addCookie(cookie) вам нужно cookie.saveTo(request, response).


в 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();
        }
    }
}