Після прочитання допису Джеффа в блозі щодо захисту ваших файлів cookie: HttpOnly . Я хотів би застосувати файли cookie HttpOnly у своєму веб-додатку.
Як сказати tomcat використовувати для сеансів лише файли cookie http?
Після прочитання допису Джеффа в блозі щодо захисту ваших файлів cookie: HttpOnly . Я хотів би застосувати файли cookie HttpOnly у своєму веб-додатку.
Як сказати tomcat використовувати для сеансів лише файли cookie 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 тут призначені лише для старих контейнерів. Будь ласка, використовуйте прийняту відповідь 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.
Будьте обережні, щоб не перезаписати прапорець 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);
}
}
request.isSecure()
не завжди є точним. Розглянемо вузол із збалансованим навантаженням позаду LB, який виконує прискорення SSL. Запит від браузера до балансування навантаження надходитиме через HTTPS, тоді як запит між балансиром навантаження та фактичним сервером надходитиме через звичайний HTTP. Це призведе до request.isSecure()
того false
, що браузер використовує SSL.
Якщо ваш веб-сервер підтримує специфікації 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
Для сесійних файлів 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);
}
Для файлів cookie, які я чітко встановлюю, я перейшов на використання SimpleCookie, наданого Apache Shiro . Він не успадковується від javax.servlet.http.Cookie, тому потрібно трохи більше жонглювання, щоб все працювало правильно, однак він надає властивість, встановлену HttpOnly, і вона працює з Servlet 2.5.
Для встановлення файлу cookie на відповідь, а не для того, щоб робити, response.addCookie(cookie)
вам потрібно це зробити cookie.saveTo(request, response)
.
Я знайшов у OWASP
<session-config>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
</session-config>
це також виправлено для проблеми безпеки "httponlycookies у конфігурації"
У 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();
}
}
}
Set-Cookie=
JSESSIONID = 25E8F ...; Шлях = / custompath; HttpOnly mycustomcookie1 = xxxxxxx; Шлях = / mycustomcookie2 = 1351101062602; Шлях = / mycustomcookie3 = 0; Шлях = / mycustomcookie4 = 1; Шлях = /; Забезпечити mycustomcookie5 = 4000; Закінчується = Субота, 22 жовтня 2022 17:51:02 за Грінвичем; Шлях = / Щось ще я роблю не так?