Hi Jinwoo,

Thank you for your analysis. I apologize for not being precise in my original 
explanation. TCCL would not automatically apply security filters. When I looked 
at the session mgmt code, it bypasses Geode's serialization infrastructure 
during reconstruction which if we fix to use existing infrastructure that 
applies whitelist-only filtering when `validate-serializable-objects=true` is 
configured.

I believe when `validate-serializable-objects=false`, then by default its 
initialized as `serializationFilter = new NullStreamSerialFilter()` and 
provides no protection, but when set to `true` it should be initialized to 
SanctionedSerializablesFilterPattern, which should not allow any classes to 
deserialize (`!*`) by default unless user configures whitelisted classes using 
`serializable-object-filter`. So the TCCL approach would require users to 
configure their session classes in `serializable-object-filter`, which is 
actually aligns with Geode's security philosophy of requiring explicit user 
configuration for deserialization.

Looking at earlier fixes CVE-2022-37021 (JMX over RMI Deserialization), we let 
user configure the protection rather than built-in security. Should session 
management follow Geode's consistent "user-configured security" pattern, or 
require a built-in security?

### **TCCL Approach:**
- **User Configuration Required**:
     - `validate-serializable-objects=true`
     - 
`serializable-object-filter=com.enterprise.model.**,com.enterprise.dto.**`
- **Breaking Change**: Sessions would reject unconfigured
- **Unified Architecture**: Same filtering system across cache operations and 
sessions
- **Security by Default**: No deserialization without explicit user 
configuration.

If this doesnt solve what is required for the new security fix that is provided 
by PR-7941, I am good to go ahead with the approach proposed in the PR.

Sai
On 2025/12/05 22:46:31 Jinwoo Hwang via dev wrote:
> Hi Sai,
> 
> Thank you for taking the time to review this PR and propose an alternative 
> architectural approach. I genuinely appreciate your thoughtful consideration 
> of how this could integrate with Geode's existing infrastructure.
> 
> I'd like to better understand the security coverage of your proposed Thread 
> Context ClassLoader approach. You mentioned two key benefits:
> 
> "Closes the vulnerability immediately"
> "Uses ALL existing Geode security filters"
> 
> I want to make sure I understand this correctly. My current implementation 
> explicitly blocks:
> 
> -26 specific gadget classes (InvokerTransformer, ChainedTransformer, 
> TemplatesImpl, ObjectFactory, MethodClosure, JndiRefForwardingDataSource, 
> etc.)
> -10 dangerous package patterns (org.apache.commons.collections.functors., 
> org.springframework.beans.factory., java.rmi.*, etc.)
> 
> Could you help me understand how your proposed approach would block these 
> same classes? Specifically:
> 
> 1.Which existing Geode filter(s) block these gadget chains?
> I traced through the code and found that serializationFilter defaults to 
> NullStreamSerialFilter (line 294 in InternalDataSerializer.java). Looking at 
> the implementation:
> 
> // NullStreamSerialFilter.java
> public class NullStreamSerialFilter implements StreamSerialFilter {
>   @Override
>   public void setFilterOn(ObjectInputStream objectInputStream) {
>     // Do nothing, this is the case where we don't filter.
>   }
> }
> This is explicitly documented as "Implementation of StreamSerialFilter that 
> does nothing" with the comment "Do nothing, this is the case where we don't 
> filter." So by default, no filtering is applied.
> 
> 2.Does sanctioned-geode-core-serializables.txt contain gadget blocking 
> entries?
> I examined this file (485 lines) and found it contains only Apache Geode 
> internal classes (exceptions, cache operations, admin/management, PDX 
> serialization).
> This appears to be a whitelist of Geode-internal classes for cluster 
> operations, not a security blocklist. It contains 485 Geode classes but zero 
> gadget chain blocking entries.
> 
> Regarding your statement that this "closes the vulnerability immediately" - I 
> want to understand the mechanism. The vulnerability exists because malicious 
> gadget chains (like InvokerTransformer) can be deserialized without any 
> validation. For the vulnerability to be closed:
> 
> -These specific classes must be blocked during deserialization, OR
> -An allowlist must reject classes not explicitly permitted
> 
> Could you clarify which of these mechanisms the TCCL approach uses? From my 
> code analysis, I see that BlobHelper.deserializeBlob() calls through to 
> InternalDataSerializer which applies serializationFilter (currently 
> NullStreamSerialFilter by default). This appears to provide no blocking of 
> gadget chains.
> 
> I may be misunderstanding how Geode's existing filter infrastructure works. 
> If there's existing gadget chain protection in Geode that I'm missing, I'd be 
> very grateful if you could point me to the specific code or configuration 
> that provides this protection.
> 
> I've invested considerable effort creating 28 unit tests in this PR covering 
> gadget blocking, resource limits, and various configuration scenarios - all 
> demonstrating that SafeDeserializationFilter successfully blocks known attack 
> chains. Could you share examples or point me to existing tests that 
> demonstrate how TCCL prevents classes like InvokerTransformer from being 
> deserialized and executed? That would really help me understand the 
> protection mechanism you're describing.
> 
> My goal is to understand whether the Thread Context ClassLoader approach 
> provides equivalent security coverage to the explicit 
> SafeDeserializationFilter, or if additional work would be needed to add 
> gadget chain protection to Geode's core infrastructure.
> 
> Specific concern: If we adopt the TCCL approach without gadget blocking, an 
> attacker could still send a malicious InvokerTransformer object in a session 
> attribute. The TCCL would successfully load the class (improving 
> compatibility), but the gadget chain would execute, achieving RCE. Is there a 
> mechanism I'm missing that prevents this?
> 
> I'm completely open to integrating with Geode's existing infrastructure if it 
> can provide the same security guarantees. I just want to make sure we don't 
> inadvertently leave the vulnerability open while we work on architectural 
> improvements.
> 
> Thank you again for your guidance and expertise on this.
> 
> 
> Best regards,
> 
> Jinwoo Hwang (he/him/his)
> 
> 
> 
> SAS® Research and Development
> 
> http://JinwooHwang.com<http://jinwoohwang.com/>
> 
> 
> 
> From: Sai Boorlagadda <[email protected]>
> Date: Friday, December 5, 2025 at 1:59 PM
> To: [email protected] <[email protected]>
> Subject: Re: PR 7941 - introduces session deserialization discussion
> 
> EXTERNAL
> 
> Hi Jinwoo,
> 
> Thanks for your thorough analysis on my feedback. After reviewing your 
> analysis, I'd like to propose an alternative approach that leverages Geode's 
> existing security infrastructure rather than creating parallel filtering 
> systems.
> 
> ## The Core Issue
> The vulnerability exists because session management bypasses Geode's robust 
> ClassLoader resolution and uses manual `ClassLoaderObjectInputStream` 
> reconstruction:
> 
> ```java
> // Current vulnerable code in GemfireHttpSession.getAttribute() (lines 
> 147-149)
> ObjectInputStream ois = new ClassLoaderObjectInputStream(
>     new ByteArrayInputStream(baos.toByteArray()), loader);
> tmpObj = ois.readObject();  // No filtering applied!
> ```
> 
> ## Proposed Solution: Thread Context ClassLoader
> Instead of creating new filtering infrastructure, we can leverage Geode's 
> existing `ClassPathLoader` delegation chain:
> 
> ```java
> // Secure alternative using existing infrastructure in GemfireHttpSession.java
> ClassLoader originalTCCL = Thread.currentThread().getContextClassLoader();
> try {
>     Thread.currentThread().setContextClassLoader(webAppClassLoader);
>     // Uses ALL existing Geode filters + secure ClassLoader resolution
>     // BlobHelper → DataSerializer → InternalDataSerializer → ClassPathLoader
>     return BlobHelper.deserializeBlob(serializedData);
> } finally {
>     Thread.currentThread().setContextClassLoader(originalTCCL);
> }
> ```
> 
> ## Why This Works
> Geode's `ClassPathLoader.java` already follows this delegation order:
> 1. Custom loaders
> 2. **Thread context ClassLoader** ← We set this to web app ClassLoader
> 3. Geode's ClassLoader
> 4. System ClassLoader
> 
> This approach:
> - ✅ **Closes the vulnerability** using existing filtered deserialization
> - ✅ **Maintains ClassLoader isolation** for web applications
> - ✅ **Leverages proven infrastructure** instead of duplicating it
> - ✅ **Provides consistent security model** across all Geode components
> 
> ## Benefits Over Dual Filtering
> - **Simpler architecture** - single security model
> - **Better maintainability** - no parallel infrastructure
> - **Future-proof** - automatically benefits from Geode security enhancements
> - **Lower risk** - uses battle-tested deserialization paths
> 
> ## Evidence This Works
> The existing test `BlobHelperWithThreadContextClassLoaderTest.java` proves 
> that `BlobHelper.deserializeBlob()` already handles ClassLoader mismatches 
> correctly using Geode's `ClassPathLoader` mechanism.
> 
> I believe this approach addresses both the immediate security concern and 
> long-term architectural consistency. Would you be open to exploring this 
> direction?
> 
> Best regards,
> Sai
> 
> On 2025/12/05 17:04:54 Jinwoo Hwang via dev wrote:
> > Hi Sai,
> >
> > Thank you very much for your careful review and for raising these important 
> > architectural considerations. I appreciate your insights and the 
> > thoughtfulness you bring to ensuring Apache Geode’s security.
> >
> > I’d like to provide some context on why I took the dual-filter approach 
> > intentionally and how it aligns with established security practices. 
> > Comprehensive details along with the architectural diagram are available 
> > here: 
> > https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Fgeode%2Fpull%2F7941%23issuecomment-3617666432&data=05%7C02%7CJinwoo.Hwang%40sas.com%7C32961c14aeee46edf7a308de3430558c%7Cb1c14d5c362545b3a4309552373a0c2f%7C0%7C0%7C639005579398526167%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=5yjPttOwctBkDkjKtXLMwCFNu72ffVyu8FV0xN%2Fp2K8%3D&reserved=0<https://github.com/apache/geode/pull/7941#issuecomment-3617666432>
> >
> > Rationale for Separate Filters
> >
> > The two filters address fundamentally different trust boundaries and threat 
> > models:
> > -HTTP/Session (SafeDeserializationFilter, 80 classes, always active): 
> > Protects against external attackers, session hijacking, and unsafe user 
> > input.
> > -Cluster/Internal (validate-serializable-objects, 485 classes, optional): 
> > Protects internal replication, peer-to-peer communication, and cluster 
> > integrity.
> >
> > This separation reflects standard defense-in-depth architecture (Spring 
> > Security, AWS, Kubernetes, Hazelcast, Microsoft SDL). Each boundary 
> > requires independent policies; merging them could weaken security.
> >
> > Addressing Your Discussion Points
> >
> > -Extending existing infrastructure: Not ideal. Cluster filters protect 
> > internal data, while SafeDeserializationFilter targets the HTTP boundary.
> > -Unified configuration: Unification would blur security boundaries; these 
> > configurations are intended to be managed by different roles.
> > -Migration path: PR-7941 includes 80 common JDK classes in the allowlist. 
> > Existing session data works without migration.
> > -Threat models: The filters address distinct threats, external HTTP 
> > attackers vs compromised cluster members with context-specific policies.
> >
> > PR-7941 introduces this new HTTP boundary layer to close the critical 
> > vulnerability while keeping cluster-level defenses optional.
> >
> > I hope this provides clarity on the architectural reasoning and why 
> > maintaining two separate filters is necessary. I value your guidance and 
> > would be happy to discuss this further if helpful.
> >
> >
> > Best regards,
> >
> > Jinwoo Hwang (he/him/his)
> >
> >
> >
> > SAS® Research and Development
> >
> > https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fprotect.checkpoint.com%2Fv2%2Fr01%2F___http%3A%2F%2FJinwooHwang.com___.YzJ1OnNhc2luc3RpdHV0ZTpjOm86YWU3NGI5MDUyYmY4ZjkwMDNlMWJhMTUzODY2NTRjMjY6NzowMDFiOmFmNzhlZDUxNjg0N2ZiZTBkN2I3NzViNzQxMjkzNjI4MTAzZDE4ZjZlZTk5ZDlkZjMzNmE2MDhjNjVjYWU2ZjQ6cDpUOk4&data=05%7C02%7CJinwoo.Hwang%40sas.com%7C32961c14aeee46edf7a308de3430558c%7Cb1c14d5c362545b3a4309552373a0c2f%7C0%7C0%7C639005579398538858%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=zGdP%2BWep7zl9inav35XDU7dzggxV9OOvocUtKkCid6c%3D&reserved=0<https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fprotect.checkpoint.com%2Fv2%2Fr01%2F___http%3A%2F%2Fjinwoohwang.com%2F___.YzJ1OnNhc2luc3RpdHV0ZTpjOm86YWU3NGI5MDUyYmY4ZjkwMDNlMWJhMTUzODY2NTRjMjY6NzoxN2JhOmYyYWRkYWNmM2ZlMDkxNjg1ZDU0MTc0OGZmMWQ4NjAzZjFkZWRlN2ZlMWI5MzBkNzI2YWFkOTU1YTA1MDRjNzU6cDpUOk4&data=05%7C02%7CJinwoo.Hwang%40sas.com%7C32961c14aeee46edf7a308de3430558c%7Cb1c14d5c362545b3a4309552373a0c2f%7C0%7C0%7C639005579398546427%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=hFE2rzwJMPAOxTnkhI6DXDY6D55aqPpR%2FgCupCB3ZrM%3D&reserved=0><https://protect.checkpoint.com/v2/r01/___http://JinwooHwang.com___.YzJ1OnNhc2luc3RpdHV0ZTpjOm86YWU3NGI5MDUyYmY4ZjkwMDNlMWJhMTUzODY2NTRjMjY6NzowMDFiOmFmNzhlZDUxNjg0N2ZiZTBkN2I3NzViNzQxMjkzNjI4MTAzZDE4ZjZlZTk5ZDlkZjMzNmE2MDhjNjVjYWU2ZjQ6cDpUOk4>
> >
> >
> >
> > From: Sai Boorlagadda <[email protected]>
> > Date: Thursday, December 4, 2025 at 12:18 PM
> > To: [email protected] <[email protected]>
> > Subject: PR 7941 - introduces session deserialization discussion
> >
> > EXTERNAL
> >
> > Hi Geode Community,
> >
> > I've been reviewing PR-7941 which addresses critical deserialization
> > vulnerabilities in session management. The implementation is solid and
> > well-engineered, but I'd like to step back and discuss the architectural
> > approach before we proceed.
> >
> > ## Current PR Approach
> > PR-7941 introduces SafeDeserializationFilter - a new, session-specific
> > filtering system that operates independently of Geode's existing
> > serialization infrastructure.
> >
> > ## Architectural Concern
> >
> > This creates a dual filtering system:
> > 1. Existing Geode filters (GlobalSerialFilterConfiguration,
> > ReflectiveFacadeStreamSerialFilter) for region data
> >
> > 2. New SafeDeserializationFilter for session attributes
> > Since sessions are stored in Geode regions, session data
> > potentially goes through BOTH filtering systems, creating:
> > - Configuration complexity (two separate whitelist systems)
> > - Operational burden (maintaining dual security policies)
> > - User confusion (different config for sessions vs regions)
> > - Potential security gaps (inconsistent policies)
> >
> > ## Discussion Points
> > 1. Should we extend existing Geode serialization infrastructure instead?
> > 2. How do we provide unified configuration for users?
> > 3. What's the migration path for existing session deployments?
> > 4. How do we handle the different threat models (web apps vs distributed
> > cache)?
> >
> > ## Proposed Alternatives
> > - Extend SerializableObjectConfig with session-specific options
> > - Integrate with existing SanctionedSerializablesService
> > - Provide session-specific sanctioned-serializables files
> > - Unified validate-session-serializable-objects configuration
> >
> > I believe the security problem is real and urgent, but want to ensure
> > we choose the right architectural approach for the long term.
> >
> > Thoughts?
> >
> > Best regards,
> > Sai Boorlagadda
> >
> 

Reply via email to