## https://sploitus.com/exploit?id=81E26AF9-DF79-5E5C-8AFA-8994AD840D4D
# CVE-2026-42779 โ Apache MINA Deserialization Filter Bypass to RCE
**CVSS 3.1:** 9.8 CRITICAL `AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`
**CWE:** CWE-502 Deserialization of Untrusted Data
**Reporter:** Venkatraman Kumar, Securin
**Advisory:** [Apache Mailing List](https://lists.apache.org/thread/fhlx5k91hrkgyzh7yk1nghrn3k27gxy0)
## Overview
Apache MINA versions **2.1.0 through 2.1.11** and **2.2.0 through 2.2.6** contain a deserialization filter bypass in `AbstractIoBuffer.resolveClass()`. The `acceptMatchers` allowlist โ intended to restrict which Java classes can be deserialized โ is completely skipped when `ObjectStreamClass.forClass()` returns `null`.
An attacker with network access to a MINA endpoint using `ObjectSerializationCodecFactory` can craft a protocol payload that bypasses the class filter, enabling **full Remote Code Execution** via standard Java deserialization gadget chains (e.g., Commons Collections).
This is an **incomplete fix** for CVE-2026-41635. The original patch was applied to the 2.0.x branch but was never backported to 2.1.x or 2.2.x due to a merge oversight.
## Affected Versions
| Branch | Vulnerable | Fixed |
|--------|-----------|-------|
| 2.1.x | 2.1.0 โ 2.1.11 | **2.1.12** |
| 2.2.x | 2.2.0 โ 2.2.6 | **2.2.7** |
## Root Cause
The vulnerability is in `AbstractIoBuffer.resolveClass()`, which handles class resolution during Java object deserialization.
MINA uses a custom serialization protocol with two class descriptor types:
- **Type 0** โ non-Serializable classes, primitives, and arrays (standard Java class descriptor format)
- **Type 1** โ Serializable classes (compact class name format)
In the vulnerable code, the `acceptMatchers` filter is **only checked in the type-1 branch** (when `forClass()` returns non-null). The type-0 branch calls `Class.forName()` directly, bypassing the filter entirely:
```java
// AbstractIoBuffer.java โ VULNERABLE (2.2.6)
protected Class resolveClass(ObjectStreamClass desc) {
Class clazz = desc.forClass();
if (clazz == null) {
// BUG: No acceptMatchers check โ filter completely bypassed
return Class.forName(name, false, classLoader);
} else {
// Filter only applied here
for (ClassNameMatcher matcher : acceptMatchers) { ... }
}
}
```
The fix in 2.2.7 moves the filter check **before** the branch:
```java
// AbstractIoBuffer.java โ FIXED (2.2.7)
protected Class resolveClass(ObjectStreamClass desc) {
String className = desc.getName();
// Filter applied FIRST, regardless of forClass() result
if (!acceptMatchers.stream().anyMatch(m -> m.matches(className))) {
throw new ClassNotFoundException("Class not in accept list " + className);
}
Class clazz = desc.forClass();
// ... safe resolution follows
}
```
## Exploitation
### Attack Flow
```
Attacker Vulnerable MINA Server
| |
| 1. Craft MINA payload with type-0 |
| descriptors for gadget chain classes |
| |
| 2. Send to endpoint using |
| ObjectSerializationCodecFactory -------->|
| |
| 3. readClassDescriptor() reads type-0|
| โ delegates to super (std Java) |
| |
| 4. resolveClass() sees forClass()==null
| โ Class.forName() WITHOUT filter |
| |
| 5. Gadget chain fully deserialized |
| โ readObject() triggers chain |
| โ Runtime.exec() fires |
| |
| RCE ACHIEVED |
```
### Preconditions
1. Target application uses `IoBuffer.getObject()` or `ObjectSerializationCodecFactory`
2. Target has `accept()` configured (applications without a filter were already exploitable via CVE-2026-41635)
3. A gadget chain library (Commons Collections, Spring, etc.) is on the classpath
### Key Insight
The attacker **controls the serialized byte stream**. By using type-0 class descriptors (instead of type-1) for Serializable gadget chain classes, every class in the deserialization graph bypasses the `acceptMatchers` filter, regardless of the application's allowlist configuration.
## Proof of Concept
Three PoCs demonstrate escalating impact:
| PoC | What it proves |
|-----|---------------|
| `FilterBypassPoC.java` | Filter bypass for primitives, non-Serializable classes, arrays |
| `CraftedBypassPoC.java` | Attacker-crafted type-0 payloads bypass filter for ANY Serializable class |
| `RcePoC.java` | Full RCE via CC6 gadget chain through the filter bypass |
### 1. Filter Bypass (MINA 2.2.6 โ Vulnerable)
Classes not in the accept list are deserialized without restriction:

### 2. Crafted Payload โ Arbitrary Class Loading
An attacker crafts MINA protocol payloads with type-0 descriptors to load any class past a `String`-only accept list:

### 3. Full RCE โ Command Execution
CC6-variant gadget chain (HashSet โ TiedMapEntry โ LazyMap โ ChainedTransformer โ `Runtime.exec()`) achieves command execution through the filter bypass:

### 4. Filter Bypass (MINA 2.2.7 โ Patched)
The same tests are blocked on the fixed version:

### 5. RCE Blocked (MINA 2.2.7 โ Patched)
The gadget chain is rejected by the filter:

## Reproduction
```bash
# Clone and build the vulnerable version
git clone https://github.com/apache/mina.git /tmp/apache-mina
cd /tmp/apache-mina
git checkout 2.2.6
mvn install -pl mina-core -DskipTests -q
# Download commons-collections (for RCE PoC)
curl -sL "https://repo1.maven.org/maven2/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar" \
-o commons-collections-3.2.2.jar
# Compile the PoCs
javac -cp mina-core/target/mina-core-2.2.6.jar FilterBypassPoC.java
javac -cp mina-core/target/mina-core-2.2.6.jar CraftedBypassPoC.java
javac -cp mina-core/target/mina-core-2.2.6.jar:commons-collections-3.2.2.jar RcePoC.java
# Run filter bypass PoC
java -cp .:mina-core/target/mina-core-2.2.6.jar FilterBypassPoC
# Run crafted payload PoC
java -cp .:mina-core/target/mina-core-2.2.6.jar CraftedBypassPoC
# Run full RCE PoC
java -Dorg.apache.commons.collections.enableUnsafeSerialization=true \
--add-opens java.base/java.util=ALL-UNNAMED \
--add-opens java.base/java.lang.reflect=ALL-UNNAMED \
-cp .:mina-core/target/mina-core-2.2.6.jar:commons-collections-3.2.2.jar \
RcePoC
```
**Requirements:** JDK 11+ and Maven
## Remediation
Upgrade to Apache MINA **2.1.12** or **2.2.7**.
If upgrading is not immediately possible:
- Do not use `IoBuffer.getObject()` or `ObjectSerializationCodecFactory` with untrusted input
- Consider using a JEP 290 serialization filter as an additional defense layer
## Timeline
| Date | Event |
|------|-------|
| 2026-05-01 | Advisory published by Apache MINA PMC |
| 2026-05-01 | Fixed versions 2.1.12 and 2.2.7 released |
| 2026-05-02 | This PoC developed and tested |
## References
- [Apache MINA Advisory](https://lists.apache.org/thread/fhlx5k91hrkgyzh7yk1nghrn3k27gxy0)
- [CVE Record](https://vulners.com/cve/CVE-2026-42779)
- [NVD Entry](https://nvd.nist.gov/vuln/detail/CVE-2026-42779)
- [Apache MINA Downloads](https://mina.apache.org/downloads-mina_2_2.html)
## Disclaimer
This proof of concept is provided for **defensive security research, education, and authorized penetration testing only**. Use responsibly and only against systems you have permission to test.