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 1605e109aaa8df757452533d3559f7c6d735c2b8 Author: Jinwoo Hwang <[email protected]> AuthorDate: Tue Dec 9 14:52:13 2025 -0500 Add ObjectInputFilter security documentation for HTTP Session Management - Add comprehensive security guide for configuring deserialization protection - Document JEP 290 ObjectInputFilter pattern syntax and examples - Include best practices, troubleshooting, and migration guidance - Add navigation link in HTTP Session Management chapter overview --- .../http_session_mgmt/chapter_overview.html.md.erb | 4 + .../session_security_filter.html.md.erb | 325 +++++++++++++++++++++ 2 files changed, 329 insertions(+) diff --git a/geode-docs/tools_modules/http_session_mgmt/chapter_overview.html.md.erb b/geode-docs/tools_modules/http_session_mgmt/chapter_overview.html.md.erb index d0513b459f..e2616ca2a2 100644 --- a/geode-docs/tools_modules/http_session_mgmt/chapter_overview.html.md.erb +++ b/geode-docs/tools_modules/http_session_mgmt/chapter_overview.html.md.erb @@ -51,6 +51,10 @@ These modules are included with the <%=vars.product_name_long%> product distribu This section describes the configuration of non-sticky sessions. +- **[Securing HTTP Session Deserialization](../../tools_modules/http_session_mgmt/session_security_filter.html)** + + Configure ObjectInputFilter (JEP 290) to protect against deserialization vulnerabilities and secure your session data. + - **[HTTP Session Management Module for Tomcat](../../tools_modules/http_session_mgmt/session_mgmt_tomcat.html)** You set up and use the module by modifying Tomcat's `server.xml` and `context.xml` files. Supports Tomcat 10.1 and later (Jakarta EE). diff --git a/geode-docs/tools_modules/http_session_mgmt/session_security_filter.html.md.erb b/geode-docs/tools_modules/http_session_mgmt/session_security_filter.html.md.erb new file mode 100644 index 0000000000..2632826cc8 --- /dev/null +++ b/geode-docs/tools_modules/http_session_mgmt/session_security_filter.html.md.erb @@ -0,0 +1,325 @@ +--- +title: Securing HTTP Session Deserialization +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +This topic describes how to configure session deserialization security using ObjectInputFilter (JEP 290) to protect against deserialization vulnerabilities. + +## <a id="overview" class="no-quick-link"></a>Overview + +Apache Geode HTTP Session Management uses Java serialization to store session attributes in the distributed cache. To protect against deserialization attacks, you can configure an ObjectInputFilter that controls which classes are allowed to be deserialized. + +**Key Benefits:** + +- **Application-Level Security**: Each web application defines its own security policy +- **Zero-Downtime Configuration**: Changes take effect on WAR deployment, no cluster restart required +- **Defense in Depth**: Explicit allowlist prevents gadget chain attacks +- **Backward Compatible**: Existing applications continue to work without configuration + +## <a id="security-warning" class="no-quick-link"></a>Security Warning + +**Without a configured filter, session deserialization has NO restrictions.** Any serializable class can be deserialized, leaving your application vulnerable to: + +- Remote Code Execution (RCE) +- Denial of Service (DoS) +- Arbitrary object instantiation attacks + +**Always configure a deserialization filter for production deployments.** + +## <a id="basic-config" class="no-quick-link"></a>Basic Configuration + +### Step 1: Add Filter Pattern to web.xml + +Add a context parameter to your application's `web.xml`: + +``` xml +<web-app> + <context-param> + <param-name>serializable-object-filter</param-name> + <param-value>com.myapp.model.**;java.lang.**;!*</param-value> + </context-param> + + <!-- Your existing filter configuration --> + <filter> + <filter-name>gemfire-session-filter</filter-name> + <filter-class>org.apache.geode.modules.session.filter.SessionCachingFilter</filter-class> + </filter> + <!-- ... --> +</web-app> +``` + +### Step 2: Deploy WAR File + +Deploy or redeploy your WAR file to the application server. The filter takes effect immediately—no cluster restart required. + +## <a id="pattern-syntax" class="no-quick-link"></a>Pattern Syntax + +The filter pattern follows [JEP 290](https://openjdk.org/jeps/290) syntax: + +| Pattern | Meaning | +|---------|---------| +| `com.myapp.**` | Allow all classes in `com.myapp` package and subpackages | +| `com.myapp.model.User` | Allow specific class only | +| `java.lang.**` | Allow all classes in `java.lang` package | +| `!com.dangerous.**` | Explicitly reject package (takes precedence) | +| `!*` | Reject everything else (default deny) | + +**Pattern Evaluation Order:** + +1. Patterns are evaluated left-to-right +2. Rejection patterns (`!`) take precedence over allowlist patterns +3. First matching pattern determines the result +4. Always end with `!*` for default deny + +## <a id="examples" class="no-quick-link"></a>Configuration Examples + +### Minimal Configuration + +Allow only your application models and essential Java classes: + +``` xml +<param-value> + com.myapp.model.**; + java.lang.**;java.util.**; + !* +</param-value> +``` + +### E-Commerce Application + +``` xml +<param-value> + com.shop.model.**; + com.shop.cart.**; + com.payment.dto.**; + java.lang.**;java.util.**;java.time.**; + !* +</param-value> +``` + +### Multi-Module Application + +``` xml +<param-value> + com.company.common.**; + com.company.customer.**; + com.company.order.**; + java.lang.**;java.util.**;java.math.BigDecimal; + !com.company.internal.**; + !* +</param-value> +``` + +### Rejecting Specific Classes + +``` xml +<param-value> + com.myapp.**; + !com.myapp.deprecated.**; + !com.myapp.legacy.OldClass; + java.lang.**;java.util.**; + !* +</param-value> +``` + +## <a id="multi-app" class="no-quick-link"></a>Multi-Application Deployments + +Each web application has its own isolated security policy: + +**Application 1 (E-commerce):** +``` xml +<param-value> + com.shop.model.**; + com.payment.**; + java.lang.**;java.util.**; + !* +</param-value> +``` + +**Application 2 (Analytics):** +``` xml +<param-value> + com.analytics.**; + com.ml.models.**; + java.lang.**;java.util.**; + !* +</param-value> +``` + +**Application 3 (CMS):** +``` xml +<param-value> + com.cms.content.**; + java.lang.**;java.util.**; + !* +</param-value> +``` + +Each application's sessions can only deserialize classes allowed by its specific filter pattern. + +## <a id="best-practices" class="no-quick-link"></a>Best Practices + +### 1. Use Explicit Allowlists + +**Don't:** +``` xml +<param-value>*</param-value> <!-- Allows everything, insecure --> +``` + +**Do:** +``` xml +<param-value> + com.myapp.safe.**; + java.lang.**;java.util.**; + !* +</param-value> +``` + +### 2. Always End with `!*` + +This creates a default-deny policy where only explicitly allowed classes can be deserialized. + +### 3. Be Specific with Package Names + +**Less secure:** +``` xml +<param-value>com.**;!*</param-value> <!-- Too broad --> +``` + +**More secure:** +``` xml +<param-value>com.myapp.model.**;!*</param-value> <!-- Specific --> +``` + +### 4. Include Essential Java Packages + +Most applications need these: +``` xml +java.lang.**; +java.util.**; +java.time.**; +``` + +### 5. Test Thoroughly + +After configuring the filter: + +1. Test all session operations (create, read, update, delete) +2. Verify session attributes deserialize correctly +3. Test session failover scenarios +4. Monitor logs for `ObjectInputFilter` rejections + +## <a id="troubleshooting" class="no-quick-link"></a>Troubleshooting + +### ClassNotFoundException or Deserialization Failures + +**Symptom:** Session attributes fail to deserialize after adding filter + +**Solution:** Add the missing class package to your filter pattern: + +``` xml +<param-value> + com.myapp.model.**; + com.thirdparty.library.**; <!-- Add missing package --> + java.lang.**;java.util.**; + !* +</param-value> +``` + +### Filter Not Taking Effect + +**Symptom:** Filter pattern changes don't apply + +**Solution:** + +1. Verify `web.xml` is packaged correctly in the WAR +2. Redeploy the WAR file completely +3. Check application server logs for errors +4. Verify parameter name is exactly `serializable-object-filter` + +### Session Attribute Classes Rejected + +**Symptom:** Logs show "ObjectInputFilter rejected class: com.myapp.NewClass" + +**Solution:** Add the class or package to your allowlist: + +``` xml +<param-value> + com.myapp.model.**; + com.myapp.NewClass; <!-- Add specific class --> + java.lang.**;java.util.**; + !* +</param-value> +``` + +## <a id="migration" class="no-quick-link"></a>Migration Guide + +### For Existing Applications + +1. **Identify Session Attribute Classes** + - List all classes stored in HTTP sessions + - Include transitive dependencies (classes referenced by session objects) + +2. **Create Filter Pattern** + - Start with your application packages + - Add essential Java packages + - End with `!*` + +3. **Test in Development** + - Deploy with filter enabled + - Exercise all session operations + - Fix any deserialization failures + +4. **Deploy to Production** + - Add filter to `web.xml` + - Redeploy WAR file (zero downtime) + - Monitor logs for unexpected rejections + +### Backward Compatibility + +**Without Filter Configuration:** +- Sessions continue to work as before +- No breaking changes +- No security protection (vulnerable) + +**With Filter Configuration:** +- Explicit security policy enforced +- Only allowed classes can be deserialized +- Protected against deserialization attacks + +## <a id="security-reference" class="no-quick-link"></a>Security Reference + +### JEP 290 + +The filter implementation uses Java's [JEP 290: Filter Incoming Serialization Data](https://openjdk.org/jeps/290), which provides: + +- Per-stream filtering capability +- Pattern-based class allowlists/denylists +- Built-in protection against known gadget chains + +### Additional Resources + +- [OWASP Deserialization Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html) +- [Java Serialization Security Best Practices](https://www.oracle.com/java/technologies/javase/seccodeguide.html#8) + +## <a id="related-topics" class="no-quick-link"></a>Related Topics + +- [Setting Up the HTTP Module for Tomcat](tomcat_setting_up_the_module.html) +- [Setting Up the HTTP Module for tc Server](tc_setting_up_the_module.html) +- [HTTP Session Management Quick Start](quick_start.html)
