有没有一种方法可以配置Tomcat7在所有情况下创建带有安全标志的JSESSIONID cookie?
通常的配置导致Tomcat仅在通过https进行连接时才使用安全标志标记会话cookie。然而,在我的生产场景中,Tomcat支持一个反向代理/负载均衡器,它处理(并终止)https连接,并通过http联系Tomcat。
即使连接是通过纯http进行的,我也可以用Tomcat在会话cookie上强制使用安全标志吗?
最终,与我最初的测试相反,web.xml解决方案在Tomcat7上对我有效。
例如,我将这个片段添加到web.xml中,即使反向代理通过纯HTTP联系tomcat,它也会将会话cookie标记为安全的。
<session-config>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
</session-config>
ServletContext.getSessionCookieConfig().setSecure(true)
另一种类似于Mark的方法是使用SessionCookieConfig
,但在JNDI配置的上下文侦听器中设置它:
代码:
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;
}
}
}
内部web.xml:
...
<listener>
<listener-class>
org.mitre.caasd.servlet.init.JndiSessionCookieConfigListener
</listener-class>
</listener>
...
在您的上下文中.xml:
...
<Environment name="JndiSessionCookieConfigListener/secure"
type="java.lang.String"
override="false"
value="true" />
...
这允许您在部署环境中的运行时设置所有会话cookie配置。因此,您可以使用相同的webapp(war文件)在本地进行开发(在没有https的地方),在生产中,您总是需要https。
注意,OWASP文档中提到了这种方法
您可以执行以下操作,通过http使用安全的JSESSIONID cookie。
对于Tomcat版本:7.x/8.x/9.x
转到Tomcat
->conf
文件夹打开web.xml
并在session-config
部分添加以下内容:
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
除此之外,建议启用SameSite
属性。
其目的是防止cookie被包含在跨站点请求中,以减轻不同的客户端攻击,如CSRF、XS Leaks和XSS。
转到->conf
文件夹打开context.xml
在<Context>
标签下方的文件中添加以下行:
<CookieProcessor className="org.apache.tomcat.util.http.Rfc6265CookieProcessor" sameSiteCookies="strict" />
现在重新启动tomcat服务器并在浏览器中-->DevTools-->应用程序,您可以确认更改。