2013-02-20 10 views
21

C'è un modo per configurare Tomcat 7 per creare un cookie JSESSIONID con un flag sicuro in tutte le occasioni?Forzare Tomcat a utilizzare cookie JSESSIONID sicuro su http

I risultati di configurazione usuali nel cookie di segnalazione di Tomcat con il flag di sicurezza solo se la connessione viene effettuata tramite https. Tuttavia, nel mio scenario di produzione, Tomcat è dietro un proxy inverso/bilanciamento del carico che gestisce (e termina) la connessione https e contatta tomcat su http.

Posso in qualche modo forzare il flag di protezione sul cookie di sessione con Tomcat, anche se la connessione avviene tramite semplice http?

risposta

29

Alla fine, contrariamente alle mie prove iniziali, soluzione web.xml ha lavorato per me su Tomcat 7.

Ad es Ho aggiunto questo snippet a web.xml e contrassegna il cookie di sessione come sicuro anche quando i contatti del proxy inverso vengono archiviati su un semplice HTTP.

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

ServletContext.getSessionCookieConfig(). SetSecure (vero)

+1

Da servlet 3 http://docs.oracle.com/javaee/6/api/javax/servlet/SessionCookieConfig.html –

1

Un altro approccio, simile a Marco, sarebbe quella di utilizzare il SessionCookieConfig, ma metterlo in un contesto ascoltatore dalla configurazione JNDI:

Il codice:

import javax.naming.Context; 
import javax.naming.InitialContext; 
import javax.naming.NamingException; 
import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 
import javax.servlet.SessionCookieConfig; 


import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 


public class JndiSessionCookieConfigListener implements ServletContextListener { 
    private static final Logger logger = LoggerFactory.getLogger(JndiSessionCookieConfigListener.class); 

    private volatile Context jndiSessionCookieConfig; 
    private volatile SessionCookieConfig sessionCookieConfig; 

    @Override 
    public void contextInitialized(ServletContextEvent sce) { 
     String listenerName = getClass().getSimpleName(); 
     try { 
      logger.info("JNDI override session cookie config found for {}", listenerName); 
      jndiSessionCookieConfig = (Context) new InitialContext().lookup(
        "java:comp/env/" + listenerName); 
     } 
     catch (NamingException e) { 
      logger.info("No JNDI override session cookie config found for {}", listenerName); 
     } 

     sessionCookieConfig = sce.getServletContext().getSessionCookieConfig(); 

     String comment = getString("comment"); 
     if (comment != null) { 
      logger.debug("\t[comment]: [{}]", comment); 
      sessionCookieConfig.setComment(comment); 
     } 

     String domain = getString("domain"); 
     if (domain != null) { 
      logger.debug("\t[domain]: [{}]", domain); 
      sessionCookieConfig.setDomain(domain); 
     } 

     Boolean httpOnly = getBoolean("http-only"); 
     if (httpOnly == null) { 
      sessionCookieConfig.setHttpOnly(true); 
     } 
     else { 
      logger.debug("\t[http-only]: [{}]", httpOnly); 
      sessionCookieConfig.setHttpOnly(httpOnly); 
     } 

     Integer maxAge = getInteger("max-age"); 
     if (maxAge != null) { 
      sessionCookieConfig.setMaxAge(maxAge); 
     } 

     String name = getString("name"); 
     if (name != null) { 
      logger.debug("\t[name]: [{}]", name); 
      sessionCookieConfig.setName(name); 
     } 

     String path = getString("path"); 
     if (path != null) { 
      logger.debug("\t[path]: [{}]", path); 
      sessionCookieConfig.setPath(path); 
     } 

     Boolean secure = getBoolean("secure"); 
     if (secure == null) { 
      sessionCookieConfig.setSecure(true); 
     } 
     else { 
      logger.debug("\t[secure]: [{}]", secure); 
      sessionCookieConfig.setSecure(secure); 
     } 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent sce) { 
    } 

    private Boolean getBoolean(String name) { 
     Object value; 
     try { 
      value = jndiSessionCookieConfig.lookup(name); 
      if (value instanceof Boolean) { 
       return (Boolean)value; 
      } 
      else { 
       return Boolean.valueOf(value.toString()); 
      } 
     } 
     catch (NamingException e) { 
      return null; 
     } 
    } 

    private Integer getInteger(String name) { 
     Object value; 
     try { 
      value = jndiSessionCookieConfig.lookup(name); 
      if (value instanceof Integer) { 
       return (Integer)value; 
      } 
      else { 
       return Integer.valueOf(value.toString()); 
      } 
     } 
     catch (NamingException e) { 
      return null; 
     } 
    } 

    private String getString(String name) { 
     Object value; 
     try { 
      value = jndiSessionCookieConfig.lookup(name); 
      return value.toString(); 
     } 
     catch (NamingException e) { 
      return null; 
     } 
    } 
} 

All'interno web.xml :

... 
    <listener> 
    <listener-class> 
     org.mitre.caasd.servlet.init.JndiSessionCookieConfigListener 
    </listener-class> 
    </listener> 
... 

Nel vostro context.xml:

... 
<Environment name="JndiSessionCookieConfigListener/secure" 
    type="java.lang.String" 
    override="false" 
    value="true" /> 
... 

Questo consente di impostare tutte le configurazioni cookie di sessione in fase di esecuzione nell'ambiente di distribuzione. Pertanto, è possibile utilizzare la stessa webapp (file di guerra) per eseguire lo sviluppo localmente (dove non si avrebbe https) e in produzione dove si desidera SEMPRE desidera https.

nota, questo approccio è menzionato nel OWASP documentation

Problemi correlati