Share
## 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:

![Filter bypass on vulnerable MINA 2.2.6](screenshots/01-filter-bypass-vulnerable.png)

### 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:

![Crafted payload bypass](screenshots/02-crafted-payload-bypass.png)

### 3. Full RCE โ€” Command Execution

CC6-variant gadget chain (HashSet โ†’ TiedMapEntry โ†’ LazyMap โ†’ ChainedTransformer โ†’ `Runtime.exec()`) achieves command execution through the filter bypass:

![RCE confirmed on MINA 2.2.6](screenshots/03-rce-confirmed.png)

### 4. Filter Bypass (MINA 2.2.7 โ€” Patched)

The same tests are blocked on the fixed version:

![Filter bypass blocked on MINA 2.2.7](screenshots/04-filter-bypass-patched.png)

### 5. RCE Blocked (MINA 2.2.7 โ€” Patched)

The gadget chain is rejected by the filter:

![RCE blocked on MINA 2.2.7](screenshots/05-rce-blocked-patched.png)

## 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.