Skip to content

Commit 1605e10

Browse files
committed
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
1 parent 7aad894 commit 1605e10

2 files changed

Lines changed: 329 additions & 0 deletions

File tree

geode-docs/tools_modules/http_session_mgmt/chapter_overview.html.md.erb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ These modules are included with the <%=vars.product_name_long%> product distribu
5151

5252
This section describes the configuration of non-sticky sessions.
5353

54+
- **[Securing HTTP Session Deserialization](../../tools_modules/http_session_mgmt/session_security_filter.html)**
55+
56+
Configure ObjectInputFilter (JEP 290) to protect against deserialization vulnerabilities and secure your session data.
57+
5458
- **[HTTP Session Management Module for Tomcat](../../tools_modules/http_session_mgmt/session_mgmt_tomcat.html)**
5559

5660
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).
Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
---
2+
title: Securing HTTP Session Deserialization
3+
---
4+
5+
<!--
6+
Licensed to the Apache Software Foundation (ASF) under one or more
7+
contributor license agreements. See the NOTICE file distributed with
8+
this work for additional information regarding copyright ownership.
9+
The ASF licenses this file to You under the Apache License, Version 2.0
10+
(the "License"); you may not use this file except in compliance with
11+
the License. You may obtain a copy of the License at
12+
13+
http://www.apache.org/licenses/LICENSE-2.0
14+
15+
Unless required by applicable law or agreed to in writing, software
16+
distributed under the License is distributed on an "AS IS" BASIS,
17+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
See the License for the specific language governing permissions and
19+
limitations under the License.
20+
-->
21+
22+
This topic describes how to configure session deserialization security using ObjectInputFilter (JEP 290) to protect against deserialization vulnerabilities.
23+
24+
## <a id="overview" class="no-quick-link"></a>Overview
25+
26+
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.
27+
28+
**Key Benefits:**
29+
30+
- **Application-Level Security**: Each web application defines its own security policy
31+
- **Zero-Downtime Configuration**: Changes take effect on WAR deployment, no cluster restart required
32+
- **Defense in Depth**: Explicit allowlist prevents gadget chain attacks
33+
- **Backward Compatible**: Existing applications continue to work without configuration
34+
35+
## <a id="security-warning" class="no-quick-link"></a>Security Warning
36+
37+
**Without a configured filter, session deserialization has NO restrictions.** Any serializable class can be deserialized, leaving your application vulnerable to:
38+
39+
- Remote Code Execution (RCE)
40+
- Denial of Service (DoS)
41+
- Arbitrary object instantiation attacks
42+
43+
**Always configure a deserialization filter for production deployments.**
44+
45+
## <a id="basic-config" class="no-quick-link"></a>Basic Configuration
46+
47+
### Step 1: Add Filter Pattern to web.xml
48+
49+
Add a context parameter to your application's `web.xml`:
50+
51+
``` xml
52+
<web-app>
53+
<context-param>
54+
<param-name>serializable-object-filter</param-name>
55+
<param-value>com.myapp.model.**;java.lang.**;!*</param-value>
56+
</context-param>
57+
58+
<!-- Your existing filter configuration -->
59+
<filter>
60+
<filter-name>gemfire-session-filter</filter-name>
61+
<filter-class>org.apache.geode.modules.session.filter.SessionCachingFilter</filter-class>
62+
</filter>
63+
<!-- ... -->
64+
</web-app>
65+
```
66+
67+
### Step 2: Deploy WAR File
68+
69+
Deploy or redeploy your WAR file to the application server. The filter takes effect immediately—no cluster restart required.
70+
71+
## <a id="pattern-syntax" class="no-quick-link"></a>Pattern Syntax
72+
73+
The filter pattern follows [JEP 290](https://openjdk.org/jeps/290) syntax:
74+
75+
| Pattern | Meaning |
76+
|---------|---------|
77+
| `com.myapp.**` | Allow all classes in `com.myapp` package and subpackages |
78+
| `com.myapp.model.User` | Allow specific class only |
79+
| `java.lang.**` | Allow all classes in `java.lang` package |
80+
| `!com.dangerous.**` | Explicitly reject package (takes precedence) |
81+
| `!*` | Reject everything else (default deny) |
82+
83+
**Pattern Evaluation Order:**
84+
85+
1. Patterns are evaluated left-to-right
86+
2. Rejection patterns (`!`) take precedence over allowlist patterns
87+
3. First matching pattern determines the result
88+
4. Always end with `!*` for default deny
89+
90+
## <a id="examples" class="no-quick-link"></a>Configuration Examples
91+
92+
### Minimal Configuration
93+
94+
Allow only your application models and essential Java classes:
95+
96+
``` xml
97+
<param-value>
98+
com.myapp.model.**;
99+
java.lang.**;java.util.**;
100+
!*
101+
</param-value>
102+
```
103+
104+
### E-Commerce Application
105+
106+
``` xml
107+
<param-value>
108+
com.shop.model.**;
109+
com.shop.cart.**;
110+
com.payment.dto.**;
111+
java.lang.**;java.util.**;java.time.**;
112+
!*
113+
</param-value>
114+
```
115+
116+
### Multi-Module Application
117+
118+
``` xml
119+
<param-value>
120+
com.company.common.**;
121+
com.company.customer.**;
122+
com.company.order.**;
123+
java.lang.**;java.util.**;java.math.BigDecimal;
124+
!com.company.internal.**;
125+
!*
126+
</param-value>
127+
```
128+
129+
### Rejecting Specific Classes
130+
131+
``` xml
132+
<param-value>
133+
com.myapp.**;
134+
!com.myapp.deprecated.**;
135+
!com.myapp.legacy.OldClass;
136+
java.lang.**;java.util.**;
137+
!*
138+
</param-value>
139+
```
140+
141+
## <a id="multi-app" class="no-quick-link"></a>Multi-Application Deployments
142+
143+
Each web application has its own isolated security policy:
144+
145+
**Application 1 (E-commerce):**
146+
``` xml
147+
<param-value>
148+
com.shop.model.**;
149+
com.payment.**;
150+
java.lang.**;java.util.**;
151+
!*
152+
</param-value>
153+
```
154+
155+
**Application 2 (Analytics):**
156+
``` xml
157+
<param-value>
158+
com.analytics.**;
159+
com.ml.models.**;
160+
java.lang.**;java.util.**;
161+
!*
162+
</param-value>
163+
```
164+
165+
**Application 3 (CMS):**
166+
``` xml
167+
<param-value>
168+
com.cms.content.**;
169+
java.lang.**;java.util.**;
170+
!*
171+
</param-value>
172+
```
173+
174+
Each application's sessions can only deserialize classes allowed by its specific filter pattern.
175+
176+
## <a id="best-practices" class="no-quick-link"></a>Best Practices
177+
178+
### 1. Use Explicit Allowlists
179+
180+
**Don't:**
181+
``` xml
182+
<param-value>*</param-value> <!-- Allows everything, insecure -->
183+
```
184+
185+
**Do:**
186+
``` xml
187+
<param-value>
188+
com.myapp.safe.**;
189+
java.lang.**;java.util.**;
190+
!*
191+
</param-value>
192+
```
193+
194+
### 2. Always End with `!*`
195+
196+
This creates a default-deny policy where only explicitly allowed classes can be deserialized.
197+
198+
### 3. Be Specific with Package Names
199+
200+
**Less secure:**
201+
``` xml
202+
<param-value>com.**;!*</param-value> <!-- Too broad -->
203+
```
204+
205+
**More secure:**
206+
``` xml
207+
<param-value>com.myapp.model.**;!*</param-value> <!-- Specific -->
208+
```
209+
210+
### 4. Include Essential Java Packages
211+
212+
Most applications need these:
213+
``` xml
214+
java.lang.**;
215+
java.util.**;
216+
java.time.**;
217+
```
218+
219+
### 5. Test Thoroughly
220+
221+
After configuring the filter:
222+
223+
1. Test all session operations (create, read, update, delete)
224+
2. Verify session attributes deserialize correctly
225+
3. Test session failover scenarios
226+
4. Monitor logs for `ObjectInputFilter` rejections
227+
228+
## <a id="troubleshooting" class="no-quick-link"></a>Troubleshooting
229+
230+
### ClassNotFoundException or Deserialization Failures
231+
232+
**Symptom:** Session attributes fail to deserialize after adding filter
233+
234+
**Solution:** Add the missing class package to your filter pattern:
235+
236+
``` xml
237+
<param-value>
238+
com.myapp.model.**;
239+
com.thirdparty.library.**; <!-- Add missing package -->
240+
java.lang.**;java.util.**;
241+
!*
242+
</param-value>
243+
```
244+
245+
### Filter Not Taking Effect
246+
247+
**Symptom:** Filter pattern changes don't apply
248+
249+
**Solution:**
250+
251+
1. Verify `web.xml` is packaged correctly in the WAR
252+
2. Redeploy the WAR file completely
253+
3. Check application server logs for errors
254+
4. Verify parameter name is exactly `serializable-object-filter`
255+
256+
### Session Attribute Classes Rejected
257+
258+
**Symptom:** Logs show "ObjectInputFilter rejected class: com.myapp.NewClass"
259+
260+
**Solution:** Add the class or package to your allowlist:
261+
262+
``` xml
263+
<param-value>
264+
com.myapp.model.**;
265+
com.myapp.NewClass; <!-- Add specific class -->
266+
java.lang.**;java.util.**;
267+
!*
268+
</param-value>
269+
```
270+
271+
## <a id="migration" class="no-quick-link"></a>Migration Guide
272+
273+
### For Existing Applications
274+
275+
1. **Identify Session Attribute Classes**
276+
- List all classes stored in HTTP sessions
277+
- Include transitive dependencies (classes referenced by session objects)
278+
279+
2. **Create Filter Pattern**
280+
- Start with your application packages
281+
- Add essential Java packages
282+
- End with `!*`
283+
284+
3. **Test in Development**
285+
- Deploy with filter enabled
286+
- Exercise all session operations
287+
- Fix any deserialization failures
288+
289+
4. **Deploy to Production**
290+
- Add filter to `web.xml`
291+
- Redeploy WAR file (zero downtime)
292+
- Monitor logs for unexpected rejections
293+
294+
### Backward Compatibility
295+
296+
**Without Filter Configuration:**
297+
- Sessions continue to work as before
298+
- No breaking changes
299+
- No security protection (vulnerable)
300+
301+
**With Filter Configuration:**
302+
- Explicit security policy enforced
303+
- Only allowed classes can be deserialized
304+
- Protected against deserialization attacks
305+
306+
## <a id="security-reference" class="no-quick-link"></a>Security Reference
307+
308+
### JEP 290
309+
310+
The filter implementation uses Java's [JEP 290: Filter Incoming Serialization Data](https://openjdk.org/jeps/290), which provides:
311+
312+
- Per-stream filtering capability
313+
- Pattern-based class allowlists/denylists
314+
- Built-in protection against known gadget chains
315+
316+
### Additional Resources
317+
318+
- [OWASP Deserialization Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html)
319+
- [Java Serialization Security Best Practices](https://www.oracle.com/java/technologies/javase/seccodeguide.html#8)
320+
321+
## <a id="related-topics" class="no-quick-link"></a>Related Topics
322+
323+
- [Setting Up the HTTP Module for Tomcat](tomcat_setting_up_the_module.html)
324+
- [Setting Up the HTTP Module for tc Server](tc_setting_up_the_module.html)
325+
- [HTTP Session Management Quick Start](quick_start.html)

0 commit comments

Comments
 (0)