Domanda

Dopo aver letto il post sul blog di Jeff su Protezione dei cookie:HttpOnly.Vorrei implementare i cookie HttpOnly nella mia applicazione web.

Come si dice a Tomcat di utilizzare i cookie solo http per le sessioni?

È stato utile?

Soluzione

httpOnly è supportato a partire da Tomcat 6.0.19 e Tomcat 5.5.28.

Vedi il registro delle modifiche voce per il bug 44382.

L'ultimo commento per bug 44382 States, "Questo è stato applicato a 5.5.x e sarà incluso in 5.5.28 in poi." Tuttavia, non sembra che sia stato rilasciato 5.5.28.

La funzionalità httpOnly può essere abilitata per tutte le webapp in conf/contesto.xml:

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

La mia interpretazione è che funziona anche per un contesto individuale impostandolo sul desiderato Contesto ingresso dentro conf/server.xml (nello stesso modo di cui sopra).

Altri suggerimenti

Aggiornamento:La roba JSessionid qui è solo per i contenitori più vecchi.Si prega di utilizzare la risposta attualmente accettata da JT a meno che tu non stia utilizzando <Tomcat 6.0.19 o <Tomcat 5.5.28 o un altro contenitore che non supporta i cookie Httponly JSessionid come opzione di configurazione.

Quando imposti i cookie nella tua app, utilizza

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

Tuttavia, in molte webapp, il cookie più importante è l'identificatore di sessione, che viene impostato automaticamente dal contenitore come cookie JSESSIONID.

Se utilizzi solo questo cookie, puoi scrivere un ServletFilter per reimpostare i cookie in uscita, forzando JSESSIONID a HttpOnly.La pagina a http://keepitlocked.net/archive/2007/11/05/java-and-httponly.aspx http://alexsmolen.com/blog/?p=16 suggerisce di aggiungere quanto segue in un filtro.

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

ma tieni presente che questo sovrascriverà tutti i cookie e imposterà solo ciò che indichi qui in questo filtro.

Se utilizzi cookie aggiuntivi rispetto al cookie JSESSIONID, dovrai estendere questo codice per impostare tutti i cookie nel filtro.Questa non è un'ottima soluzione nel caso di cookie multipli, ma forse è una soluzione rapida accettabile per la configurazione solo JSESSIONID.

Tieni presente che man mano che il tuo codice si evolve nel tempo, c'è un brutto bug nascosto che ti aspetta quando dimentichi questo filtro e provi a impostare un altro cookie da qualche altra parte nel tuo codice.Ovviamente non si sistemerà.

Questo è davvero un trucco però.Se usi Tomcat e puoi compilarlo, dai un'occhiata all'eccellente suggerimento di Shabaz di applicare il supporto HttpOnly a Tomcat.

Fai attenzione a non sovrascrivere il flag del cookie ";secure" nelle sessioni https.Questo flag impedisce al browser di inviare il cookie tramite una connessione http non crittografata, rendendo sostanzialmente inutile l'uso di https per richieste legittime.

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);
    }
}

Per i cookie di sessione non sembra essere ancora supportato in Tomcat.Vedi la segnalazione del bug È necessario aggiungere il supporto per il parametro del cookie di sessione HTTPOnly.Per ora è possibile trovare una soluzione un po' complicata Qui, che sostanzialmente si riduce all'applicazione manuale di patch a Tomcat.Non riesco davvero a trovare un modo semplice per farlo in questo momento, a questo punto temo.

Per riassumere la soluzione alternativa, comporta il download della versione 5.5 fonte, quindi modificare l'origine nei seguenti punti:

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);
}

Se il tuo server web supporta le specifiche Serlvet 3.0, come Tomcat 7.0+, puoi utilizzare di seguito in web.xml COME:

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

Come menzionato nei documenti:

HttpOnly:Specifica se i cookie di tracciamento della sessione creati da questa applicazione Web saranno contrassegnati come httponly

Sicuro:Specifica se i cookie di tracciamento della sessione creati da questa applicazione Web saranno contrassegnati come sicuri anche se la richiesta che ha avviato la sessione corrispondente utilizza HTTP semplice anziché HTTPS

Per favore riferisci a come impostare httponly e cookie di sessione per l'applicazione Web Java

inoltre va notato che l'attivazione di HttpOnly interromperà le applet che richiedono l'accesso con stato alla jvm.

le richieste http dell'applet non utilizzeranno il cookie jsessionid e potrebbero essere assegnate a un Tomcat diverso.

Per i cookie che sto impostando esplicitamente, sono passato a use SimpleCookie fornito da Apache Shiro.Non eredita da javax.servlet.http.Cookie quindi ci vuole un po' più di giocoleria per far funzionare tutto correttamente, tuttavia fornisce un set di proprietà HttpOnly e funziona con Servlet 2.5.

Per impostare un cookie su una risposta, invece di farlo response.addCookie(cookie) devi fare cookie.saveTo(request, response).

In Tomcat6, puoi abilitare in modo condizionale dalla tua classe HTTP Listener:

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

Utilizzando questa 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();
        }
    }
}

Ho trovato dentro OWASP

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

questo risolve anche il problema di sicurezza "httponlycookies in config".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top