diff --git a/java/org/apache/catalina/session/ManagerBase.java b/java/org/apache/catalina/session/ManagerBase.java
index 0e6b97f80..99f6cc04a 100644
--- a/java/org/apache/catalina/session/ManagerBase.java
+++ b/java/org/apache/catalina/session/ManagerBase.java
@@ -37,6 +37,7 @@
import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Engine;
+import org.apache.catalina.Globals;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleState;
@@ -226,8 +227,31 @@ public abstract class ManagerBase extends LifecycleMBeanBase implements Manager
private boolean warnOnSessionAttributeFilterFailure;
- // ------------------------------------------------------------- Properties
+ // ------------------------------------------------------------ Constructors
+ public ManagerBase() {
+ if (Globals.IS_SECURITY_ENABLED) {
+ // Minimum set required for default distribution/persistence to work
+ // plus String
+ setSessionAttributeValueClassNameFilter(
+ "java\\.lang\\.(?:Boolean|Integer|Long|Number|String)");
+ setWarnOnSessionAttributeFilterFailure(true);
+ }
+ }
+
+
+ // -------------------------------------------------------------- Properties
+
+ /**
+ * Obtain the regular expression used to filter session attribute based on
+ * attribute name. The regular expression is anchored so it must match the
+ * entire name
+ *
+ * @return The regular expression currently used to filter attribute names.
+ * {@code null} means no filter is applied. If an empty string is
+ * specified then no names will match the filter and all attributes
+ * will be blocked.
+ */
public String getSessionAttributeNameFilter() {
if (sessionAttributeNamePattern == null) {
return null;
diff --git a/java/org/apache/catalina/session/StandardManager.java b/java/org/apache/catalina/session/StandardManager.java
index 1df2b581e..936f30f33 100644
--- a/java/org/apache/catalina/session/StandardManager.java
+++ b/java/org/apache/catalina/session/StandardManager.java
@@ -191,10 +191,12 @@ protected void doLoad() throws ClassNotFoundException, IOException {
}
Loader loader = null;
ClassLoader classLoader = null;
+ Log logger = null;
try (FileInputStream fis = new FileInputStream(file.getAbsolutePath());
- BufferedInputStream bis = new BufferedInputStream(fis);) {
+ BufferedInputStream bis = new BufferedInputStream(fis)) {
Context c = getContext();
loader = c.getLoader();
+ logger = c.getLogger();
if (loader != null) {
classLoader = loader.getClassLoader();
}
@@ -204,7 +206,9 @@ protected void doLoad() throws ClassNotFoundException, IOException {
// Load the previously unloaded active sessions
synchronized (sessions) {
- try (ObjectInputStream ois = new CustomObjectInputStream(bis, classLoader)) {
+ try (ObjectInputStream ois = new CustomObjectInputStream(bis, classLoader, logger,
+ getSessionAttributeValueClassNamePattern(),
+ getWarnOnSessionAttributeFilterFailure())) {
Integer count = (Integer) ois.readObject();
int n = count.intValue();
if (log.isDebugEnabled())
diff --git a/java/org/apache/catalina/session/StoreBase.java b/java/org/apache/catalina/session/StoreBase.java
index 679ac983b..09c88e01d 100644
--- a/java/org/apache/catalina/session/StoreBase.java
+++ b/java/org/apache/catalina/session/StoreBase.java
@@ -215,7 +215,20 @@ public void processExpires() {
*/
protected ObjectInputStream getObjectInputStream(InputStream is) throws IOException {
BufferedInputStream bis = new BufferedInputStream(is);
- return new CustomObjectInputStream(bis, Thread.currentThread().getContextClassLoader());
+
+ CustomObjectInputStream ois;
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+ if (manager instanceof ManagerBase) {
+ ManagerBase managerBase = (ManagerBase) manager;
+ ois = new CustomObjectInputStream(bis, classLoader, manager.getContext().getLogger(),
+ managerBase.getSessionAttributeValueClassNamePattern(),
+ managerBase.getWarnOnSessionAttributeFilterFailure());
+ } else {
+ ois = new CustomObjectInputStream(bis, classLoader);
+ }
+
+ return ois;
}
diff --git a/java/org/apache/catalina/util/CustomObjectInputStream.java b/java/org/apache/catalina/util/CustomObjectInputStream.java
index b6ec5f88a..5d1fb58fa 100644
--- a/java/org/apache/catalina/util/CustomObjectInputStream.java
+++ b/java/org/apache/catalina/util/CustomObjectInputStream.java
@@ -18,9 +18,18 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.lang.reflect.Proxy;
+import java.util.Collections;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
+
+import org.apache.juli.logging.Log;
+import org.apache.tomcat.util.res.StringManager;
/**
* Custom subclass of ObjectInputStream
that loads from the
@@ -32,14 +41,26 @@
*/
public final class CustomObjectInputStream extends ObjectInputStream {
+ private static final StringManager sm = StringManager.getManager(CustomObjectInputStream.class);
+
+ private static final WeakHashMapWARN
level logging if an attribute is filtered. These
options are avaialble for all of the Manager implementations that ship
- with Tomcat. (markt)
+ with Tomcat. When a SecurityManager
is used filtering will
+ be enabled by default. (markt)
diff --git a/webapps/docs/config/cluster-manager.xml b/webapps/docs/config/cluster-manager.xml
index e0a7a9ddc..6ebe69efc 100644
--- a/webapps/docs/config/cluster-manager.xml
+++ b/webapps/docs/config/cluster-manager.xml
@@ -198,7 +198,9 @@
length or null
, all attributes are eligible for
replication. The pattern is anchored so the fully qualified class name
must fully match the pattern. If not specified, the default value of
- null
will be used.
null
will be used unless a SecurityManager
is
+ enabled in which case the default will be
+ java\\.lang\\.(?:Boolean|Integer|Long|Number|String)
.
GET_ALL_SESSIONS
message to other
@@ -217,7 +219,8 @@
attribute, should this be logged at WARN
level? If
WARN
level logging is disabled then it will be logged at
DEBUG
. The default value of this attribute is
- false
.
+ false
unless a SecurityManager
is enabled in
+ which case the default will be true
.
null
, all attributes are eligible for
replication. The pattern is anchored so the fully qualified class name
must fully match the pattern. If not specified, the default value of
- null
will be used.
+ null
will be used unless a SecurityManager
is
+ enabled in which case the default will be
+ java\\.lang\\.(?:Boolean|Integer|Long|Number|String)
.
WARN
level? If
WARN
level logging is disabled then it will be logged at
DEBUG
. The default value of this attribute is
- false
.
+ false
unless a SecurityManager
is enabled in
+ which case the default will be true
.
null
, all attributes are eligible for
distribution. The pattern is anchored so the fully qualified class name
must fully match the pattern. If not specified, the default value of
- null
will be used.
+ null
will be used unless a SecurityManager
is
+ enabled in which case the default will be
+ java\\.lang\\.(?:Boolean|Integer|Long|Number|String)
.
WARN
level? If
WARN
level logging is disabled then it will be logged at
DEBUG
. The default value of this attribute is
- false
.
+ false
unless a SecurityManager
is enabled in
+ which case the default will be true
.
null
, all attributes are eligible for
distribution. The pattern is anchored so the fully qualified class name
must fully match the pattern. If not specified, the default value of
- null
will be used.
+ null
will be used unless a SecurityManager
is
+ enabled in which case the default will be
+ java\\.lang\\.(?:Boolean|Integer|Long|Number|String)
.
WARN
level? If
WARN
level logging is disabled then it will be logged at
DEBUG
. The default value of this attribute is
- false
.
+ false
unless a SecurityManager
is enabled in
+ which case the default will be true
.