java - secure - non httponly session cookies identified
Obligar a Tomcat a usar una cookie JSESSIONID segura sobre http (3)
Al final, al contrario de mis pruebas iniciales, la solución web.xml me funcionó en Tomcat 7.
Por ejemplo, agregué este fragmento a web.xml y marca la cookie de sesión como segura incluso cuando el proxy inverso contacta a tomcat en lugar de HTTP sin formato.
<session-config>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
</session-config>
¿Hay alguna manera de configurar Tomcat 7 para crear la cookie JSESSIONID con una bandera segura en todas las ocasiones?
La configuración habitual da como resultado que Tomcat señale la cookie de sesión con indicador de seguridad solo si la conexión se realiza a través de https. Sin embargo, en mi escenario de producción, Tomcat está detrás de un proxy inverso / balanceador de carga que maneja (y finaliza) la conexión https y se comunica con tomcat en lugar de http.
¿Puedo de alguna manera forzar la marca segura en la cookie de sesión con Tomcat, a pesar de que la conexión se realiza a través de http simple?
Otro enfoque, similar al de Mark, sería usar SessionCookieConfig
, pero SessionCookieConfig
en un escucha de contexto desde la configuración JNDI:
El código:
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;
}
}
}
Dentro de web.xml:
...
<listener>
<listener-class>
org.mitre.caasd.servlet.init.JndiSessionCookieConfigListener
</listener-class>
</listener>
...
En su context.xml:
...
<Environment name="JndiSessionCookieConfigListener/secure"
type="java.lang.String"
override="false"
value="true" />
...
Esto le permite establecer todas las configuraciones de cookies de sesión en tiempo de ejecución en el entorno de despliegue . Por lo tanto, podría usar la misma aplicación web (archivo war) para desarrollar localmente (donde no tendría https) y en producción donde SIEMPRE quisiera https.
Tenga en cuenta que este enfoque se menciona en la documentación de OWASP
ServletContext.getSessionCookieConfig (). SetSecure (true)