Comment configurer HttpOnly cookies dans tomcat / java webapps?

après avoir lu le billet de Jeff sur protéger vos Cookies: HttpOnly . J'aimerais implémenter des cookies HttpOnly dans mon application web.

Comment dire à tomcat d'utiliser des cookies http uniquement pour les sessions?

71
demandé sur Cheekysoft 2008-08-29 01:09:30

8 réponses

httpOnly est supporté à partir de Tomcat 6.0.19 et Tomcat 5.5.28.

voir l'entrée changelog pour le bogue 44382.

Le Dernier commentaire pour le bogue 44382 indique," ceci a été appliqué à 5.5.x et sera inclus à partir de 5.5.28."Toutefois, il ne semble pas que 5.5.28 a été libéré.

la fonctionnalité httpOnly peut être activée pour toutes les applications Web en conf/contexte.xml :

<Context useHttpOnly="true">
...
</Context>

mon interprétation est qu'il fonctionne également pour un contexte individuel en le mettant sur le contexte entrée dans conf/server.xml (de la même manière que ci-dessus).

61
répondu jt. 2009-07-06 16:46:12

mise à Jour: Le JSESSIONID trucs ici est uniquement pour les conteneurs. Veuillez utiliser la réponse de jt est acceptée à moins que vous utilisez < Tomcat 6.0.19 ou < Tomcat 5.5.28 ou un autre conteneur qui ne supporte pas les cookies HttpOnly JSESSIONID en tant qu'option de configuration.

lors de la configuration des cookies dans votre application, utilisez

response.setHeader( "Set-Cookie", "name=value; HttpOnly");

cependant, dans de nombreux webapps, le cookie le plus important est le identifiant de session, qui est automatiquement défini par le conteneur comme étant le cookie JSESSIONID.

si vous n'utilisez que ce cookie, vous pouvez écrire un ServletFilter pour re-configurer les cookies en sortant, forçant JSESSIONID à HttpOnly. La page à http://keepitlocked.net/archive/2007/11/05/java-and-httponly.aspx http://alexsmolen.com/blog/?p=16 suggère d'ajouter ce qui suit dans un filtre.

if (response.containsHeader( "SET-COOKIE" )) {
  String sessionid = request.getSession().getId();
  response.setHeader( "SET-COOKIE", "JSESSIONID=" + sessionid 
                      + ";Path=/<whatever>; Secure; HttpOnly" );
} 

mais notez que cela va écraser tous les cookies et ne définir ce que vous déclarez ici dans ce filtre.

si vous utilisez des cookies supplémentaires pour le cookie JSESSIONID, vous devrez étendre ce code pour configurer tous les cookies dans le filtre. Ce n'est pas une bonne solution dans le cas de cookies multiples, mais c'est peut-être une solution rapide acceptable pour la configuration de JSESSIONID seulement.

veuillez noter que votre code évolue avec le temps, il y a un méchant bug caché qui vous attend quand vous oubliez ce filtre et essayez de mettre un autre cookie ailleurs dans votre code. Bien sûr, il ne sera pas en jeu.

c'est vraiment un piratage. Si vous utilisez Tomcat et que vous pouvez le compiler, jetez un coup d'oeil à L'excellente suggestion de Shabaz de patcher le support HttpOnly dans Tomcat.

19
répondu Cheekysoft 2012-06-11 08:57:47

veillez à ne pas écraser l'indicateur de cookie"; secure " dans https-sessions. Cette option empêche le navigateur d'envoyer le cookie sur une connexion http non cryptée, ce qui rend essentiellement inutile l'utilisation de https pour les requêtes légitimes.

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);
    }
}
14
répondu Hendrik Brummermann 2012-04-22 23:02:46

pour les cookies de session, il ne semble pas encore être pris en charge dans Tomcat. Voir le rapport de bogue besoin d'ajouter le support pour le paramètre de cookie de session HTTPOnly . Un travail quelque peu impliqué pour le moment peut être trouvé ici , qui se résume essentiellement à réparer manuellement Tomcat. Je n'arrive pas à trouver un moyen facile de le faire en ce moment.

pour résumer la solution de rechange, il s'agit de télécharger les 5,5 source , puis changer la source dans les endroits suivants:

org.Apache.Catalina.connecteur.Demande.java

//this is what needs to be changed
//response.addCookieInternal(cookie);

//this is whats new
response.addCookieInternal(cookie, true);
}

org.Apache.Catalina.connectorResponse.addcookieinterne

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);
}
9
répondu Shabaz 2008-08-28 21:36:07

si votre serveur web supporte Serlvet 3.0 spec, comme tomcat 7.0+, vous pouvez utiliser ci-dessous dans web.xml comme:

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

comme mentionné dans docs:

HttpOnly : spécifie si des cookies de suivi de session créés par cette application web sera marquée comme HttpOnly

Sécurisé : Spécifie si des cookies de suivi de session créés par ceci application web sera marqué comme sécurisé même si la demande qui a initié le la session correspondante utilise un HTTP simple au lieu de HTTPS

consultez comment définir httponly et cookie de session pour les applications web java

7
répondu Alireza Fattahi 2018-06-20 04:02:23

il convient également de noter que le fait d'activer HttpOnly briserait les applets qui nécessitent un accès stateeful à la jvm.

les requêtes http Applet n'utiliseront pas le cookie jsessionid et pourront être affectées à un tomcat différent.

2
répondu Pete Brumm 2010-08-18 20:33:57

pour les cookies que je configure explicitement, je suis passé à utiliser SimpleCookie fourni par Apache Shiro . Il n'hérite pas de javax.servlet.http.Cookie donc il faut un peu plus de jonglage pour que tout fonctionne correctement mais il fournit un ensemble de propriétés HttpOnly et il fonctionne avec Servlet 2.5.

pour configurer un cookie sur une réponse, plutôt que de faire response.addCookie(cookie) vous devez faire cookie.saveTo(request, response) .

2
répondu Jesse Vogt 2013-01-30 17:49:40

dans Tomcat6, vous pouvez activer sous condition depuis votre classe D'écouteurs HTTP:

public void contextInitialized(ServletContextEvent event) {                 
   if (Boolean.getBoolean("HTTP_ONLY_SESSION")) HttpOnlyConfig.enable(event);
}

utilisant cette classe

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();
        }
    }
}
0
répondu Systemsplanet 2015-12-08 03:21:21