Как настроить файлы cookie HttpOnly в веб-приложениях tomcat / java?


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

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

8 71

8 ответов:

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 здесь только для старых контейнеров. Пожалуйста, используйте JT в настоящее время принят ответ, если только вы используете

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

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

однако во многих веб-приложениях наиболее важным файлом 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" );
} 

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

Если вы используете дополнительные файлы cookie для файла cookie JSESSIONID, вам нужно будет расширить этот код, чтобы установить все файлы cookie в фильтре. Это не отличное решение в случае нескольких файлов cookie, но, возможно, является приемлемым быстрым решением для установки только 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);
    }
}

для сеансовых файлов cookie он, похоже, еще не поддерживается в Tomcat. Смотрите отчет об ошибке необходимо добавить поддержку параметра cookie сеанса HTTPOnly. Несколько вовлеченный обходной путь на данный момент можно найти здесь, который в основном сводится к ручному исправлению Tomcat. Не могу найти простой способ сделать это в этот момент, в этот момент я боюсь.

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

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

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

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

орг.апаш.Каталина.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 spec, как tomcat 7.0+, вы можете использовать ниже в web.xml как:

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

Как упоминалось в документах:

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

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

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

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

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

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

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

в Tomcat6 вы можете условно включить из своего класса http Listener:

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