U-Sec commented on issue #4255:
URL: 
https://github.com/apache/logging-log4j2/issues/4255#issuecomment-5393493255

   **Follow-up from the reporter — two refinements to the original report.**
   
   ## 1. Correction: global `jdk.serialFilter` DOES defend (when configured), 
and this yields an immediate workaround
   
   The original report states the `MarshalledObject` ObjectInputFilter capture 
is a no-op because FOIS never calls `setObjectInputFilter()`. That is only true 
when **no process-wide filter is configured** (the JDK default, i.e. most 
deployments). We re-ran the full PoC matrix against OpenJDK 17.0.18 with global 
filters enabled:
   
   | Global `jdk.serialFilter` | Result |
   |---|---|
   | *none configured* (JDK default) | **Exploit succeeds** — unfiltered inner 
stream |
   | `maxdepth=5;maxbytes=1000000` (commonly recommended generic filter) | 
**Exploit still succeeds.** The inner stream inside `MarshalledObject.get()` is 
a *new* stream: depth counting restarts and the payload is only ~1.3 KB / depth 
2, so generic depth/byte limits do not stop it |
   | `!java.rmi.MarshalledObject` | Blocked at the outer stream 
(`InvalidClassException: REJECTED`) |
   | `!com.example.GadgetClass` (deny a gadget class) | Blocked at the inner 
stream — **and silently**: the receiver logs the event normally (`message()` 
falls back to `SimpleMessage`), so probing attempts leave no trace |
   | allowlist without `MarshalledObject` | Blocked |
   
   Technical explanation: each `ObjectInputStream` constructor inherits the 
process-wide filter, so the filter captured by `MarshalledObject.readObject` is 
the *global* one, not null. Class-pattern filters therefore apply to both 
layers; generic depth/size filters only apply per-stream.
   
   **Immediate operator workaround (no code change needed):**
   
   ```
   -Djdk.serialFilter='!java.rmi.MarshalledObject'
   ```
   
   or any class-pattern allowlist that omits `java.rmi.MarshalledObject` / 
denies known gadget classes. This closes the receiver path until a library fix 
ships.
   
   ## 2. Additional hardening gap: FOIS does not override `resolveProxyClass`
   
   `FilteredObjectInputStream` only overrides `resolveClass()` (line 66). 
Serialized `TC_PROXYCLASS` descriptors are resolved by the default 
`resolveProxyClass()` implementation, so **the proxy interface names never pass 
through the allowlist**. For comparison, Tomcat's `CustomObjectInputStream` 
performs its `checkAllowed()` in both `resolveClass` and `resolveProxyClass`.
   
   Standalone exploitation is constrained (no dangerous `InvocationHandler` is 
present on the default allowlist), so we do not consider this an independent 
RCE — but it is a second, independent allowlist gap and should be fixed 
alongside: override `resolveProxyClass` to run the same allowlist check on 
every interface name in `interfaces[]`.
   
   Both refinements have been re-verified against the official 2.26.1 
artifacts; the PoCs are available to maintainers on request.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to