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

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

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


person ScArcher2    schedule 28.08.2008    source источник


Ответы (10)


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>

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

person jt.    schedule 06.07.2009
comment
Я использую Tomcat 5.5.36. Этот атрибут useHttpOnly работает только для cookie JSESSIONID. Я добавил этот флаг во все мои контексты, чтобы убедиться, что все файлы cookie будут добавлены; HttpOnly в конце. Однако только JSESSIONID был затронут следующим образом: Set-Cookie= JSESSIONID = 25E8F ...; Путь = / custompath; HttpOnly mycustomcookie1 = xxxxxxx; Путь = / mycustomcookie2 = 1351101062602; Путь = / mycustomcookie3 = 0; Путь = / mycustomcookie4 = 1; Путь = /; Защитите mycustomcookie5 = 4000; Срок действия истекает = сб, 22 октября 2022 г., 17:51:02 по Гринвичу; Путь = / Что еще я делаю не так? - person L. Holanda; 24.10.2012
comment
Эта документация, похоже, указывает, что флаг useHttpOnly относится только к cookie с идентификатором сеанса: tomcat.apache.org/tomcat-5.5-doc/config/ Я думаю, что это временная мера, предназначенная для защиты файлов cookie сеанса. Возможность отмечать файлы cookie как HttpOnly не входила в спецификацию сервлетов до версии 3.0 (охватывалась Tomcat 7): today.java.net/pub/a/today/2008/10/14/ - person jt.; 25.10.2012

Обновление: здесь JSESSIONID предназначен только для старых контейнеров. Используйте принятый в настоящее время ответ jt, если вы не используете ‹Tomcat 6.0.19 или‹ Tomcat 5.5.28 или другой контейнер, который не поддерживает файлы cookie HttpOnly JSESSIONID в качестве параметра конфигурации.

При установке файлов cookie в приложении используйте

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

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

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

person Cheekysoft    schedule 28.08.2008
comment
Этот код удаляет флаг; Secure, делая использование https бессмысленным. - person Hendrik Brummermann; 23.06.2010
comment
На серверах приложений для жалоб Servlet 3.0 я могу установить флаги HttpOnly и secure для файла cookie сеанса (JSESSIONID), добавив в web.xml следующее: ‹session-config› ‹cookie-config› ‹secure› true ‹/secure› ‹ только http ›true ‹/http-only› ‹/cookie-config› ‹/session-config› - person Roger Jin; 25.09.2014
comment
@RogerJin, пожалуйста, опубликуйте это как новый ответ, этот ответ 6-летней давности становится все более устаревшим. - person Cheekysoft; 25.09.2014
comment
Будьте осторожны с setHeader, потому что он удаляет все предыдущие заголовки с тем же именем. Например, он может удалить файл cookie JSESSIONID при установке пользовательского файла cookie. Вместо этого используйте response.addHeader () для пользовательских файлов cookie. - person dpinya; 18.01.2016

Будьте осторожны, чтобы не перезаписать флаг "; 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);
    }
}
person Hendrik Brummermann    schedule 23.09.2009
comment
Обратите внимание, что использование request.isSecure() не всегда точно. Рассмотрим узел с балансировкой нагрузки за LB, который выполняет ускорение SSL. Запрос от браузера к балансировщику нагрузки будет поступать по HTTPS, а запрос между балансировщиком нагрузки и фактическим сервером будет поступать по обычному протоколу HTTP. Это приведет к тому, что request.isSecure() будет false, в то время как браузер использует SSL. - person Anton; 03.08.2014

Если ваш веб-сервер поддерживает спецификацию 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: указывает, будут ли какие-либо файлы cookie отслеживания сеанса, созданные этим веб-приложением, помечены как HttpOnly.

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

См. https://stackoverflow.com/questions/15510354/how-to-set-httponly-and-session-cookie-for-java-web-appliaction

person Alireza Fattahi    schedule 23.06.2015

Для файлов cookie сеанса, похоже, это еще не поддерживается в Tomcat. См. Отчет об ошибке Необходимо добавить поддержку параметра cookie сеанса 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);
}
person Shabaz    schedule 28.08.2008

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

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

person Pete Brumm    schedule 18.08.2010

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

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

person Jesse Vogt    schedule 30.01.2013

Я нашел в OWASP

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

это также исправление проблемы безопасности "httponlycookies в конфигурации"

person Ravipati Praveen    schedule 06.12.2018

В 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();
        }
    }
}
person Systemsplanet    schedule 08.12.2015

Реализация: в Tomcat 7.x / 8.x / 9.x

Перейдите в папку Tomcat ›› conf. Откройте файл web.xml и добавьте ниже в разделе конфигурации сеанса.

    <cookie-config>
        <http-only>true</http-only>
        <secure>true</secure>
    </cookie-config>
person Akash Chatterjee    schedule 29.05.2021