This is an automated email from the ASF dual-hosted git repository.

jinwoo pushed a commit to branch support/2.0
in repository https://gitbox.apache.org/repos/asf/geode.git

commit 716a9804f68857de8716c8f9b4d62d1792ebf653
Author: Jinwoo Hwang <[email protected]>
AuthorDate: Tue Dec 9 19:55:20 2025 -0500

    Address PR review feedback: cache filter, add null check, add logging
    
    - Implement filter caching using double-checked locking with volatile 
fields to eliminate race conditions and improve performance
    - Add null check before setObjectInputFilter() for defensive programming
    - Add INFO logging when filter is configured and WARN logging when not 
configured to improve security visibility
    
    Addresses review comments by @sboorlagadda on PR #7966
---
 .../internal/filter/GemfireHttpSession.java        | 43 +++++++++++++++++++---
 .../modules/util/ClassLoaderObjectInputStream.java |  4 +-
 2 files changed, 40 insertions(+), 7 deletions(-)

diff --git 
a/extensions/geode-modules-session-internal/src/main/java/org/apache/geode/modules/session/internal/filter/GemfireHttpSession.java
 
b/extensions/geode-modules-session-internal/src/main/java/org/apache/geode/modules/session/internal/filter/GemfireHttpSession.java
index 97035bb76b..8e81b59d52 100644
--- 
a/extensions/geode-modules-session-internal/src/main/java/org/apache/geode/modules/session/internal/filter/GemfireHttpSession.java
+++ 
b/extensions/geode-modules-session-internal/src/main/java/org/apache/geode/modules/session/internal/filter/GemfireHttpSession.java
@@ -79,6 +79,13 @@ public class GemfireHttpSession implements HttpSession, 
DataSerializable, Delta
 
   private ServletContext context;
 
+  /**
+   * Cached ObjectInputFilter to avoid recreating on every deserialization.
+   * Initialized lazily on first use with double-checked locking.
+   */
+  private volatile ObjectInputFilter cachedFilter;
+  private volatile boolean filterLogged = false;
+
   /**
    * A session becomes invalid if it is explicitly invalidated or if it 
expires.
    */
@@ -108,6 +115,34 @@ public class GemfireHttpSession implements HttpSession, 
DataSerializable, Delta
     });
   }
 
+  /**
+   * Gets or creates the cached ObjectInputFilter. Uses double-checked locking 
to avoid
+   * unnecessary synchronization after initialization.
+   *
+   * @return the cached ObjectInputFilter, or null if no filter is configured
+   */
+  private ObjectInputFilter getOrCreateFilter() {
+    if (cachedFilter == null && !filterLogged) {
+      synchronized (this) {
+        if (cachedFilter == null && !filterLogged) {
+          String filterPattern = getServletContext()
+              .getInitParameter("serializable-object-filter");
+
+          if (filterPattern != null) {
+            cachedFilter = 
ObjectInputFilter.Config.createFilter(filterPattern);
+            LOG.info("ObjectInputFilter configured with pattern: {}", 
filterPattern);
+          } else {
+            LOG.warn("No ObjectInputFilter configured. Session deserialization 
is not protected " +
+                "against malicious payloads. Configure 
'serializable-object-filter' in web.xml " +
+                "to enable deserialization security.");
+          }
+          filterLogged = true;
+        }
+      }
+    }
+    return cachedFilter;
+  }
+
   /**
    * Constructor used for de-serialization
    */
@@ -145,12 +180,8 @@ public class GemfireHttpSession implements HttpSession, 
DataSerializable, Delta
           oos.writeObject(obj);
           oos.close();
 
-          // Create filter from user configuration for secure deserialization
-          String filterPattern = getServletContext()
-              .getInitParameter("serializable-object-filter");
-          ObjectInputFilter filter = filterPattern != null
-              ? ObjectInputFilter.Config.createFilter(filterPattern)
-              : null;
+          // Get or create cached filter for secure deserialization
+          ObjectInputFilter filter = getOrCreateFilter();
 
           ObjectInputStream ois = new ClassLoaderObjectInputStream(
               new ByteArrayInputStream(baos.toByteArray()), loader, filter);
diff --git 
a/extensions/geode-modules/src/main/java/org/apache/geode/modules/util/ClassLoaderObjectInputStream.java
 
b/extensions/geode-modules/src/main/java/org/apache/geode/modules/util/ClassLoaderObjectInputStream.java
index 24ee3eaf04..8acb35b54e 100644
--- 
a/extensions/geode-modules/src/main/java/org/apache/geode/modules/util/ClassLoaderObjectInputStream.java
+++ 
b/extensions/geode-modules/src/main/java/org/apache/geode/modules/util/ClassLoaderObjectInputStream.java
@@ -40,7 +40,9 @@ public class ClassLoaderObjectInputStream extends 
ObjectInputStream {
       throws IOException {
     super(in);
     this.loader = loader;
-    setObjectInputFilter(filter);
+    if (filter != null) {
+      setObjectInputFilter(filter);
+    }
   }
 
   /**

Reply via email to