Forcing Tomcat to use secure JSESSIONID cookie over http

后端 未结 3 1785
礼貌的吻别
礼貌的吻别 2020-12-08 10:29

Is there a way to configure Tomcat 7 to create JSESSIONID cookie with a secure flag in all occasions?

Usual configuration results in Tomcat flagging session cookie

相关标签:
3条回答
  • 2020-12-08 10:53

    Another approach, similar to Mark's, would be to use the SessionCookieConfig, but set it in a context listener from JNDI configuration:

    The code:

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

    Inside web.xml:

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

    In your context.xml:

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

    This allows you to set all the session cookie configurations at runtime in the deployment environment. Thus, you could use the same webapp (war file) to do development locally (where you would not have https) and in production where you would ALWAYS want https.

    Note, this approach is mentioned in the OWASP documentation

    0 讨论(0)
  • 2020-12-08 10:54

    ServletContext.getSessionCookieConfig().setSecure(true)

    0 讨论(0)
  • 2020-12-08 11:12

    In the end, contrary to my initial tests, web.xml solution worked for me on Tomcat 7.

    E.g. I added this snippet to web.xml and it marks session cookie as secure even when reverse proxy contacts tomcat over plain HTTP.

    <session-config>
        <cookie-config>
            <http-only>true</http-only>
            <secure>true</secure>
        </cookie-config>
    </session-config>
    
    0 讨论(0)
提交回复
热议问题