После прочтения сообщения блога Джеффа на странице Защита файлов 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>
Я считаю, что он также работает для отдельного контекста, устанавливая его в желаемой записи Context в conf / server.xml (в том же способ, как указано выше).
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
Обновление: здесь 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.
Будьте осторожны, чтобы не перезаписать флаг "; 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);
}
}
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.
Для файлов 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);
}
также следует отметить, что включение HttpOnly приведет к поломке апплетов, которым требуется доступ с отслеживанием состояния обратно к jvm.
HTTP-запросы апплета не будут использовать cookie jsessionid и могут быть назначены другому коту.
Для файлов 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();
}
}
}
Реализация: в Tomcat 7.x / 8.x / 9.x
Перейдите в папку Tomcat ›› conf. Откройте файл web.xml и добавьте ниже в разделе конфигурации сеанса.
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>