Як налаштувати файли cookie HttpOnly у веб-додатках tomcat / java?


Відповіді:


66

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 (таким же чином, як вище).


Я запускаю 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 за Грінвичем; Шлях = / Щось ще я роблю не так?
L. Holanda

Здається, ця документація вказує на те, що прапор 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/…
jt.

20

Оновлення: матеріали 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 і можете скомпілювати його, тоді погляньте на чудову пропозицію Шабаза вмонтувати підтримку HttpOnly в Tomcat.


8
Цей код видаляє прапорець Secure, таким чином, використання https стає безглуздим.
Hendrik Brummermann

На серверах додатків для подання скарг Servlet 3.0 я можу встановити HttpOnly та захищені прапори для файлу cookie сеансу (JSESSIONID), додавши до web.xml таке: <session-config> <cookie-config> <secure> true </secure> < http-only> true </http-only> </cookie-config> </session-config>
Роджер Джин

@RogerJin, будь ласка, опублікуйте це як нову відповідь, ця 6-річна відповідь стає все більш застарілою.
Cheekysoft

Будьте обережні з setHeader, оскільки він видаляє всі попередні заголовки з однаковим іменем. Наприклад, він може видалити файл cookie JSESSIONID, коли ви встановлюєте власний файл cookie. Натомість використовуйте response.addHeader () для власних файлів cookie
dpinya

14

Будьте обережні, щоб не перезаписати прапорець cookie "; secure" у 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);
    }
}

2
Зверніть увагу, що використання request.isSecure()не завжди є точним. Розглянемо вузол із збалансованим навантаженням позаду LB, який виконує прискорення SSL. Запит від браузера до балансування навантаження надходитиме через HTTPS, тоді як запит між балансиром навантаження та фактичним сервером надходитиме через звичайний HTTP. Це призведе до request.isSecure()того false, що браузер використовує SSL.
Антон

13

Якщо ваш веб-сервер підтримує специфікації 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

Будь ласка, зверніться до того, як встановити httponly та файли cookie сеансу для веб-програми Java


10

Для сесійних файлів 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);
}

2

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

http-запити аплету не використовуватимуть файл cookie jsessionid і можуть бути призначені іншому tomcat.


2

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

Для встановлення файлу cookie на відповідь, а не для того, щоб робити, response.addCookie(cookie)вам потрібно це зробити cookie.saveTo(request, response).


2

Я знайшов у OWASP

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

це також виправлено для проблеми безпеки "httponlycookies у конфігурації"


1

У 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();
        }
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.