Nach dem Lesen von Jeffs Blog-Beitrag zum Schutz Ihrer Cookies: HttpOnly . Ich möchte HttpOnly-Cookies in meiner Webanwendung implementieren.
Wie weist man Tomcat an, für Sitzungen nur http-Cookies zu verwenden?
Nach dem Lesen von Jeffs Blog-Beitrag zum Schutz Ihrer Cookies: HttpOnly . Ich möchte HttpOnly-Cookies in meiner Webanwendung implementieren.
Wie weist man Tomcat an, für Sitzungen nur http-Cookies zu verwenden?
Antworten:
httpOnly wird ab Tomcat 6.0.19 und Tomcat 5.5.28 unterstützt.
Siehe den Änderungsprotokolleintrag für Fehler 44382.
Der letzte Kommentar zu Fehler 44382 lautet: "Dies wurde auf 5.5.x angewendet und wird ab 5.5.28 enthalten sein." Es scheint jedoch nicht, dass 5.5.28 veröffentlicht wurde.
Die httpOnly-Funktionalität kann für alle Webanwendungen in conf / context.xml aktiviert werden :
<Context useHttpOnly="true">
...
</Context>
Meine Interpretation ist, dass es auch für einen einzelnen Kontext funktioniert, indem es auf den gewünschten Kontexteintrag in conf / server.xml gesetzt wird (auf die gleiche Weise wie oben).
Update: Das JSESSIONID-Zeug hier ist nur für ältere Container. Bitte verwenden Sie die aktuell akzeptierte Antwort von jt, es sei denn, Sie verwenden <Tomcat 6.0.19 oder <Tomcat 5.5.28 oder einen anderen Container, der keine HttpOnly JSESSIONID-Cookies als Konfigurationsoption unterstützt.
Verwenden Sie zum Setzen von Cookies in Ihrer App
response.setHeader( "Set-Cookie", "name=value; HttpOnly");
In vielen Webanwendungen ist das wichtigste Cookie jedoch die Sitzungskennung, die vom Container automatisch als JSESSIONID-Cookie festgelegt wird.
Wenn Sie nur dieses Cookie verwenden, können Sie einen ServletFilter schreiben, um die Cookies auf dem Weg nach draußen zurückzusetzen und JSESSIONID auf HttpOnly zu zwingen. Die Seite unter http://keepitlocked.net/archive/2007/11/05/java-and-httponly.aspx http://alexsmolen.com/blog/?p=16 schlägt vor, Folgendes in einen Filter aufzunehmen.
if (response.containsHeader( "SET-COOKIE" )) {
String sessionid = request.getSession().getId();
response.setHeader( "SET-COOKIE", "JSESSIONID=" + sessionid
+ ";Path=/<whatever>; Secure; HttpOnly" );
}
Beachten Sie jedoch, dass dadurch alle Cookies überschrieben werden und nur festgelegt wird, was Sie hier in diesem Filter angeben.
Wenn Sie zusätzliche Cookies zum JSESSIONID-Cookie verwenden, müssen Sie diesen Code erweitern, um alle Cookies im Filter zu setzen. Dies ist keine großartige Lösung für mehrere Cookies, aber möglicherweise eine akzeptable schnelle Lösung für das Nur-JSESSIONID-Setup.
Bitte beachten Sie, dass im Laufe der Zeit ein böser versteckter Fehler auf Sie wartet, wenn Sie diesen Filter vergessen und versuchen, ein anderes Cookie an einer anderen Stelle in Ihrem Code zu setzen. Natürlich wird es nicht eingestellt.
Dies ist jedoch wirklich ein Hack. Wenn Sie Tomcat verwenden und es kompilieren können, werfen Sie einen Blick auf Shabaz 'hervorragenden Vorschlag, die HttpOnly-Unterstützung in Tomcat zu patchen.
Bitte achten Sie darauf, das "; sichere" Cookie-Flag in https-Sessions nicht zu überschreiben. Dieses Flag verhindert, dass der Browser das Cookie über eine unverschlüsselte http-Verbindung sendet, wodurch die Verwendung von https für legitime Anforderungen grundsätzlich sinnlos wird.
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()
nicht immer korrekt ist. Stellen Sie sich einen Knoten mit Lastenausgleich hinter dem LB vor, der die SSL-Beschleunigung ausführt. Die Anforderung vom Browser an den Load Balancer erfolgt über HTTPS, während die Anforderung zwischen Load Balancer und dem tatsächlichen Server über einfaches HTTP erfolgt. Dies führt request.isSecure()
dazu false
, dass der Browser SSL verwendet.
Wenn Ihr Webserver die Serlvet 3.0-Spezifikation wie Tomcat 7.0+ unterstützt, können Sie Folgendes verwenden web.xml
:
<session-config>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
</session-config>
Wie in den Dokumenten erwähnt:
HttpOnly : Gibt an, ob von dieser Webanwendung erstellte Sitzungsverfolgungscookies als HttpOnly markiert werden
Sicher : Gibt an, ob von dieser Webanwendung erstellte Sitzungsverfolgungscookies als sicher markiert werden, selbst wenn die Anforderung, die die entsprechende Sitzung initiiert hat, einfaches HTTP anstelle von HTTPS verwendet
Bitte beachten Sie , wie Httponly und Session - Cookie für Java - Web - Anwendung setzen
Für Sitzungscookies scheint es in Tomcat noch nicht unterstützt zu werden. Siehe Fehlerbericht. Unterstützung für HTTPOnly-Sitzungscookie-Parameter muss hinzugefügt werden . Eine etwas komplizierte Problemumgehung finden Sie hier komplizierte Problemumgehung , die sich im Wesentlichen auf das manuelle Patchen von Tomcat beschränkt. Ich fürchte, ich kann derzeit keinen einfachen Weg finden, dies zu tun.
Um die Problemumgehung zusammenzufassen, müssen Sie die 5.5- Quelle herunterladen und die Quelle an den folgenden Stellen ändern:
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);
}
Es sollte auch beachtet werden, dass durch das Aktivieren von HttpOnly Applets beschädigt werden, die einen zustandsbehafteten Zugriff auf das JVM erfordern.
Die Applet-http-Anforderungen verwenden nicht das jsessionid-Cookie und werden möglicherweise einem anderen Kater zugewiesen.
Für Cookies, die ich explizit setze , habe ich auf SimpleCookie von Apache Shiro umgestellt . Es erbt nicht von javax.servlet.http.Cookie, daher ist etwas mehr Jonglieren erforderlich, damit alles ordnungsgemäß funktioniert. Es stellt jedoch einen Eigenschaftssatz HttpOnly bereit und funktioniert mit Servlet 2.5.
Um ein Cookie für eine Antwort zu setzen, response.addCookie(cookie)
müssen Sie dies tun cookie.saveTo(request, response)
.
Ich habe in OWASP gefunden
<session-config>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
</session-config>
Dies wurde auch für das Sicherheitsproblem "httponlycookies in config" behoben
In Tomcat6 können Sie von Ihrer HTTP-Listener-Klasse aus bedingt aktivieren:
public void contextInitialized(ServletContextEvent event) {
if (Boolean.getBoolean("HTTP_ONLY_SESSION")) HttpOnlyConfig.enable(event);
}
Verwenden dieser Klasse
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 ...; Pfad = / custompath; HttpOnly mycustomcookie1 = xxxxxxx; Pfad = / mycustomcookie2 = 1351101062602; Pfad = / mycustomcookie3 = 0; Pfad = / mycustomcookie4 = 1; Pfad = /; Secure mycustomcookie5 = 4000; Läuft ab = Sa, 22.10.2022 17:51:02 GMT; Pfad = / Mache ich sonst noch etwas falsch?