CVE-2026-16723 breaks a security assumption that many Java teams have relied on for years: leaving Fastjson AutoType disabled is not enough.
Alibaba’s security advisory states that Fastjson versions 1.2.68 through 1.2.83 can be vulnerable to remote code execution under stock parser defaults when the application is packaged as a Spring Boot executable fat JAR and launched with java -jar. In the affected configuration, AutoType is off, SafeMode is off, and an attacker-controlled JSON document reaches a vulnerable Fastjson parsing entry point. The advisory says the issue does not require administrators to enable AutoType and does not depend on a traditional application-classpath gadget. Alibaba verified end-to-end code execution across Spring Boot 2.x, 3.x, and 4.x and JDK 8, 11, 17, and 21. (GitHub)
That does not mean every application containing Fastjson is remotely exploitable. The dependency version, runtime package, launch method, parser configuration, input path, network exposure, and process privileges all matter. A Maven alert showing com.alibaba:fastjson:1.2.83 is evidence of a potentially affected component, not proof of reachable remote code execution.
The operational problem is nevertheless serious. Fastjson 1.2.83 was the final release in the original 1.x line, the original repository has been archived, and Alibaba does not identify a newly patched Fastjson 1.x version. The immediate official controls are enabling SafeMode or using the 1.2.83_noneautotype build, followed by migration to Fastjson2. (GitHub)
The NVD record attributes a CVSS 3.1 score of 9.0 to Alibaba’s CNA assessment, with the vector CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H. The high attack-complexity rating reflects the environmental prerequisites, but the potential impact remains total compromise of the affected Java process and resources reachable through it. The record maps the issue to CWE-20 and CWE-502. (NVD)
The Risk at a Glance
| 질문 | Confirmed answer | Security consequence |
|---|---|---|
| Which versions are affected? | Fastjson 1.2.68 through 1.2.83 | A version match requires immediate deployment and reachability review |
| Is AutoType required? | No. The official chain works with AutoType disabled | An existing autoTypeSupport=false setting does not close this issue |
| Is SafeMode required for protection? | SafeMode blocks the vulnerable @type path according to Alibaba | Enable it as an emergency control and verify it in the running process |
| Which deployment form is affected? | Spring Boot executable fat JAR launched with java -jar | Packaging and classloader behavior are part of exploitability |
| Are ordinary JAR and WAR deployments affected? | Alibaba lists plain non-Spring-Boot JARs, generic uber-JARs, and Tomcat or Jetty WAR deployments as not affected by this specific chain | Do not generalize a version alert across every Java packaging model |
| Does a fixed target class eliminate the issue? | Not necessarily | DTOs containing 개체, 지도, or similar dynamic fields may preserve the risky path |
| Is Fastjson2 affected? | Alibaba says all Fastjson2 versions are unaffected | Migration is the long-term corrective action |
| Is there a patched Fastjson 1.x release? | No newly fixed 1.x release is identified | Teams must use SafeMode, noneautotype, or migrate |
| Does dependency presence prove RCE? | 아니요 | Runtime packaging, configuration, reachability, and privilege still require validation |
The most useful response is therefore neither “all Fastjson applications are compromised” nor “we disabled AutoType years ago, so there is no problem.” The correct response is evidence-driven triage.
What Changed in CVE-2026-16723
Previous Fastjson incidents trained defenders to ask two questions:
- Is AutoType enabled or bypassable?
- Is a usable gadget class present on the application classpath?
CVE-2026-16723 changes that model. Alibaba’s advisory describes a path that remains reachable with the standard AutoType setting disabled and that does not require a traditional classpath gadget. The deployment itself supplies an important part of the behavior: Spring Boot’s executable-JAR classloader and nested-resource handling create conditions that are not present in ordinary Java packaging models. (GitHub)
That distinction matters because many enterprise controls were written around older Fastjson failure modes. Teams may have a configuration assertion such as:
ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
They may also have a policy that forbids explicit calls enabling AutoType. Those controls remain useful against older classes of Fastjson misuse, but they do not establish that CVE-2026-16723 is mitigated.
The safer configuration for the 1.x line is SafeMode:
ParserConfig.getGlobalInstance().setSafeMode(true);
SafeMode is stronger than merely disabling AutoType. Alibaba’s documentation says that SafeMode disables AutoType completely and rejects type metadata before it reaches the affected path. The same setting can be applied as a JVM system property or through fastjson.properties. (GitHub)
A second important change is the role of target-class binding. Developers often assume this call is safe:
OrderRequest request = JSON.parseObject(json, OrderRequest.class);
That assumption is too broad. Alibaba specifically warns that target-class binding is not a sufficient mitigation if the target object contains weakly typed fields such as 개체 또는 지도. A nominally fixed DTO can still create a dynamic deserialization boundary inside the object graph. (GitHub)
예를 들어
public final class WebhookRequest {
private String event;
private Map<String, Object> payload;
public String getEvent() {
return event;
}
public void setEvent(String event) {
this.event = event;
}
public Map<String, Object> getPayload() {
return payload;
}
public void setPayload(Map<String, Object> payload) {
this.payload = payload;
}
}
The outer class is fixed, but payload remains a dynamic object graph controlled by input. A security review that stops at WebhookRequest.class misses the more important question: what types can Fastjson construct below that field?
Confirmed Affected and Unaffected Conditions
Alibaba’s official scope is narrower than some early third-party descriptions. The advisory identifies Fastjson 1.2.68 through 1.2.83 as affected. Some public reports used wording such as “1.2.83 and earlier,” but that should not replace the vendor’s explicit range for CVE-2026-16723. Older releases may be unsafe for other reasons, and downgrading is not a defensible workaround. (GitHub)
The official scope can be translated into a practical matrix.
| Environment | CVE-2026-16723 assessment | 필요한 조치 |
|---|---|---|
| Fastjson 1.2.68 through 1.2.83, Spring Boot executable fat JAR, SafeMode off, untrusted JSON reaches Fastjson | Matches the documented vulnerable environment | Treat as urgent and apply SafeMode or noneautotype immediately |
| Same version and package, but SafeMode is verified true | Alibaba lists SafeMode as blocking the vulnerable path | Retain evidence, regression-test normal parsing, and plan migration |
1.2.83_noneautotype build | Vulnerable AutoType code is removed from the build | Confirm the runtime artifact and test application compatibility |
| Fastjson2 | Not affected according to Alibaba | Confirm that legacy Fastjson 1.x is not also packaged transitively |
| Plain non-Spring-Boot JAR | Not affected by the documented deployment-specific chain | Continue checking for other Fastjson vulnerabilities and unsafe configuration |
| Generic uber-JAR | Listed as not affected by Alibaba | Verify that it is genuinely generic and not a repackaged Spring Boot executable JAR |
| Tomcat or Jetty WAR deployment | Listed as not affected by the official chain | Validate the real deployment and continue normal deserialization hardening |
| Affected version exists only in a test configuration | Not a production exposure by itself | Confirm it is absent from released artifacts, images, and serverless packages |
| Version cannot be identified because code was shaded | Unknown | Inspect classes, build metadata, and vendor documentation |
| Fastjson is present but no untrusted input path is known | Potentially affected component with unproven reachability | Perform code and runtime reachability analysis rather than closing the alert |
The phrase “not affected” in this matrix applies only to the documented CVE-2026-16723 chain. It does not mean that an older Fastjson deployment is broadly secure. Fastjson 1.x has a long history of type-driven deserialization weaknesses, and unsupported or archived software creates additional maintenance risk.
Why Spring Boot Executable Fat JARs Matter
A Spring Boot executable fat JAR is not a normal flat JAR containing one application and a single set of unpacked classes. It is a structured archive designed to hold the application and its dependencies in nested locations.
A typical package contains:
application.jar
├── META-INF
│ └── MANIFEST.MF
├── org
│ └── springframework
│ └── boot
│ └── loader
├── BOOT-INF
│ ├── classes
│ │ └── com
│ │ └── example
│ │ └── Application.class
│ └── lib
│ ├── spring-boot-*.jar
│ ├── fastjson-1.2.83.jar
│ └── other-dependency.jar
Spring Boot’s launcher locates application classes under BOOT-INF/classes and dependencies under BOOT-INF/lib. Its classloader supports loading resources and classes from nested archives without unpacking every dependency onto the filesystem. Official Spring Boot documentation describes this executable-JAR structure and the launcher behavior used to make nested dependencies available at runtime. (홈)
That resource-loading model is central to CVE-2026-16723. Public technical descriptions connect the vulnerable path to Fastjson’s handling of attacker-influenced type information, resource probing, annotation metadata, and Spring Boot’s nested-JAR loader. The exact exploit mechanics should not be reduced to a single string signature, but the architectural point is clear: packaging changes classloader behavior, and classloader behavior changes the security properties of deserialization. (GitHub)
Two applications with the same Fastjson version can therefore have different exposure:
- An application deployed as a conventional WAR to an external Tomcat instance does not use the same nested-JAR classloader arrangement.
- A command-line utility packaged as a plain JAR may not expose the relevant resource-resolution behavior.
- A Spring Boot service launched with
java -jar service.jarcan match the documented prerequisite. - A container does not change this conclusion by itself. If the container runs a Spring Boot executable fat JAR, the prerequisite can still be present.
- Unpacking the Spring Boot application before launch may change the classloader path, but this should not be treated as a preferred fix. SafeMode, noneautotype, or migration is clearer and less fragile.
The packaging prerequisite also explains why ordinary SCA results are incomplete. SCA can tell a team that an affected library version is present. It generally cannot prove that the application is launched through Spring Boot’s executable-JAR loader, that an attacker controls the parsed JSON, or that SafeMode is disabled at runtime.
How to Identify the Deployment Shape
The first check is local and non-destructive:
unzip -l application.jar | grep -E 'BOOT-INF/(classes|lib)'
A Spring Boot executable JAR typically produces entries similar to:
BOOT-INF/classes/
BOOT-INF/lib/
BOOT-INF/lib/fastjson-1.2.83.jar
Inspect the manifest:
unzip -p application.jar META-INF/MANIFEST.MF
Common indicators include a Spring Boot launcher as Main-Class and the application entry point as Start-Class.
A generic example looks like:
Main-Class: org.springframework.boot.loader.launch.JarLauncher
Start-Class: com.example.Application
Launcher names differ across Spring Boot generations, so matching one exact string is weaker than inspecting the complete structure and launch process.
Check the actual process:
ps -ef | grep '[j]ava'
For a container:
docker inspect application-container \
--format '{{json .Config.Entrypoint}} {{json .Config.Cmd}}'
For Kubernetes:
kubectl get pod application-pod -o jsonpath='{.spec.containers[*].command}'
kubectl get pod application-pod -o jsonpath='{.spec.containers[*].args}'
These commands should be used only in environments the operator is authorized to inspect. The relevant evidence is not merely that a fat JAR exists, but that the deployed process launches it in the documented way.
Build pipelines often complicate the picture. A source repository may produce a thin JAR during compilation and then repackage it in a release stage. A vendor may place the application in a container image that differs from the artifact retained by the development team. A platform team may inject a Java agent, unpack dependencies, or replace the launcher.
For that reason, the security record should identify:
- The cryptographic hash of the inspected artifact.
- The image digest or release identifier.
- The Fastjson artifact found inside it.
- The launcher and startup command.
- The runtime JVM flags.
- The route or consumer that accepts untrusted JSON.
- The SafeMode state.
- The date and owner of the validation.
Without those details, “we checked the JAR” is difficult to reproduce and easy to invalidate during the next deployment.
The Vulnerability Path Without Weaponizing It

A useful technical explanation must show where the security boundary fails without publishing a production-ready exploit.
Fastjson supports JSON-to-Java object conversion. Java developers often want a parser to reconstruct concrete object types from serialized data, particularly when an object graph contains interfaces, abstract classes, or generic containers. Fastjson historically used type metadata such as @type to participate in that process.
The danger is that external data begins to influence class selection. Once a parser accepts a Java class name or equivalent type signal from an untrusted document, it is no longer processing plain data alone. It is participating in runtime type resolution.
Traditional exploitation commonly required an enabled or bypassed AutoType feature and a useful class already present in the application’s dependency graph. The attacker selected that class, supplied properties that triggered dangerous behavior, and relied on the parser to construct or invoke it. This model produced the familiar “gadget chain” language used in Java deserialization research.
Alibaba’s CVE-2026-16723 advisory says the new issue does not require that traditional classpath-gadget condition. The reported root cause involves resource probing based on attacker-influenced class information and the use of @JSONType metadata as a trust signal. In the affected Spring Boot packaging environment, nested-resource behavior allows the type-resolution process to cross a boundary that developers expected AutoType’s default-disabled state to protect. (GitHub)
A defensive abstraction of the chain is:
Untrusted JSON
│
▼
Fastjson parsing entry point
│
▼
Attacker-influenced type metadata
│
▼
Type and resource resolution
│
▼
Spring Boot nested-JAR classloader behavior
│
▼
Unexpected trust decision involving annotation metadata
│
▼
Attacker-controlled execution path
This diagram deliberately omits exploit-specific class names, remote resource locations, bytecode construction, and command execution. Those details are unnecessary for inventory, mitigation, detection, or architecture review.
Several security conclusions follow.
First, the vulnerable behavior sits below the API endpoint. Authentication, schema validation, and gateway controls may reduce exposure, but the parser remains unsafe until the underlying condition is addressed.
Second, a parser option can carry stronger security meaning than a developer expects. “AutoType is disabled” sounds absolute, but the CVE demonstrates that another internal path can make a type-related trust decision.
Third, packaging is executable behavior. Build output is not a passive container of code. A loader, launcher, module system, plugin framework, or nested archive can change which resources are visible and how type resolution occurs.
Fourth, remote code execution does not automatically mean root or host compromise. Code ordinarily begins with the identity and permissions of the Java process. The blast radius depends on whether that process can:
- Read database passwords or API tokens.
- Access cloud instance metadata.
- Use a Kubernetes service-account token.
- Write application or deployment files.
- Reach internal control planes.
- Start child processes.
- Connect to the public internet.
- Mount the Docker socket.
- Access shared storage.
- Assume cloud roles.
A low-privilege, egress-restricted container meaningfully limits impact. It does not make the deserialization flaw acceptable, but it can prevent a parser failure from becoming a wider infrastructure incident.
Relevant Fastjson Entry Points
Alibaba lists several common entry points in the affected surface:
JSON.parse(String json)
JSON.parseObject(String json)
JSON.parseObject(String json, Class<T> clazz)
The first two are easy to recognize as dynamic parsing APIs. The third often receives less scrutiny because it appears to bind the input to a known type. The official warning about 개체 그리고 지도 fields is therefore important. (GitHub)
Consider a payment notification model:
public final class PaymentNotification {
private String provider;
private String eventId;
private Object details;
public String getProvider() {
return provider;
}
public void setProvider(String provider) {
this.provider = provider;
}
public String getEventId() {
return eventId;
}
public void setEventId(String eventId) {
this.eventId = eventId;
}
public Object getDetails() {
return details;
}
public void setDetails(Object details) {
this.details = details;
}
}
The call site appears strongly typed:
PaymentNotification notification =
JSON.parseObject(body, PaymentNotification.class);
그리고 details field is not strongly typed. It permits dynamic object construction below the top-level DTO.
A safer design uses a specific data model:
public final class PaymentDetails {
private String currency;
private long amountMinor;
private String status;
// getters and setters
}
public final class PaymentNotification {
private String provider;
private String eventId;
private PaymentDetails details;
// getters and setters
}
This change does not replace SafeMode or migration. It reduces the broader architectural risk by removing a weakly typed object boundary.
The same review should cover:
Map<String, Object>Map<?, ?>List<Object>- Interface-typed fields
- Abstract base classes
- Generic extension objects
- Arbitrary metadata maps
- Plugin configuration objects
- Event envelopes with dynamic bodies
- Database records containing serialized object graphs
A metadata map containing only strings can be modeled as Map<String, String>. A finite set of event variants can be represented by an explicit event name and an application-controlled mapping. External JSON should not be allowed to name an arbitrary Java implementation class.
Where Untrusted JSON Commonly Reaches Fastjson
Internet-facing REST controllers are the obvious location, but they are not the only relevant entry point.
Webhooks
Webhook receivers commonly accept vendor-controlled or customer-controlled JSON. They may be unauthenticated, protected only by a shared secret, or exposed through a signature verification layer. If signature verification happens after parsing, the parser still processes attacker-supplied content before authenticity is established.
The safer order is:
Read bounded raw body
│
▼
Verify signature over raw bytes
│
▼
Reject invalid sender
│
▼
Validate JSON schema
│
▼
Deserialize into a fixed DTO
Message queues
A consumer may trust a Kafka, RabbitMQ, or cloud queue because the broker is internal. That trust can be misplaced if an external service can publish indirectly, a compromised producer can send arbitrary events, or tenant boundaries share the same messaging infrastructure.
Cached and stored JSON
Data written before a fix may be parsed after the fix is deployed. An attacker can sometimes place crafted JSON in a cache, database, object store, or audit queue through one code path and trigger deserialization through another.
Internal APIs
Internal services are not automatically trusted. SSRF, compromised workloads, leaked service credentials, overly broad network policies, and shared API gateways can make an internal endpoint reachable from an attacker-controlled context.
Vendor SDKs
A business application may never call Fastjson directly. A payment SDK, cloud client, identity connector, rule engine, or internal platform library may call it on the application’s behalf.
Configuration and plugin systems
Applications sometimes deserialize JSON configuration during startup or scheduled reloads. The input may come from a configuration service, uploaded plugin bundle, database row, or administrative API. These routes may not look like normal HTTP request handling, but they can still cross a trust boundary.
File-processing workflows
Uploaded JSON files, import packages, mobile synchronization archives, or support bundles may be parsed asynchronously. The absence of a direct request-response path can make such exposures harder to find and easier to overlook.
Reachability review must therefore trace data, not just URLs.
Severity, Exploitability, and Evidence Quality
Alibaba’s CNA score of 9.0 is consistent with the worst-case impact of remote code execution without authentication or user interaction. The AC:H component is equally important: successful exploitation requires a specific combination of library version, packaging model, parser state, and controllable input. (NVD)
Security teams should avoid collapsing five different evidence states into the phrase “exploited in the wild.”
| Evidence state | What it proves | What it does not prove |
|---|---|---|
| A vulnerability advisory exists | A credible technical issue has been assigned and documented | That a particular organization is exposed |
| A public proof of concept exists | Researchers can reproduce some or all of the behavior | That mass exploitation is occurring |
| Requests matching a signature are observed | Someone is scanning, testing, or sending suspicious input | That the vulnerable path was reached |
| Resource loading or network activity is observed | The request caused behavior beyond ordinary parsing | That arbitrary code executed successfully |
| A Java child process or attacker-defined action is observed | Strong evidence of successful execution | The complete scope of compromise |
| Named victims and forensic evidence are published | Confirmed real-world compromise in documented cases | That all suspicious traffic succeeded |
ThreatBook described active exploitation and reported different outcomes across deployment tests, including a stronger result in a Spring Boot fat-JAR environment and more limited resource-fetching behavior in another configuration. Imperva later reported observing attacks against organizations in multiple industries and countries. These reports increase the urgency of hunting, but public summaries did not provide enough raw evidence to independently verify the success rate or establish widespread compromise. (ThreatBook)
The NVD page published on July 23, 2026, displayed CISA-ADP SSVC data with exploitation marked 없음. The Hacker News reported on July 25 that the vulnerability was not in the CISA Known Exploited Vulnerabilities Catalog at that time. Those observations do not disprove vendor telemetry; they show that different sources were applying different evidence thresholds. (NVD)
A defensible conclusion is:
- The vulnerability is technically severe.
- Public evidence supports concern about probing and attempted exploitation.
- Publicly available information does not justify claiming that every observed request achieved RCE.
- Waiting for a confirmed named victim is not a reasonable prerequisite for applying SafeMode.
- Incident language should distinguish attempted exploitation from confirmed execution.
A Focused Disclosure Timeline
| Date | Event | Operational meaning |
|---|---|---|
| October 23, 2024 | The original Fastjson repository was archived and made read-only | The 1.x line should not be treated as an actively maintained long-term dependency |
| July 21, 2026 | Alibaba published its CVE-2026-16723 security advisory | Vendor-defined scope, prerequisites, and mitigations became available |
| July 22, 2026 | ThreatBook published an early technical report | Defenders received additional reproduction and attack-activity claims |
| July 23, 2026 | The CVE record was published through Alibaba’s CNA data | The affected range and CVSS assessment became available through NVD |
| July 24, 2026 | Imperva published telemetry and technical analysis | Public reporting suggested active targeting across multiple sectors |
| July 25, 2026 | The Hacker News summarized the vulnerability and evidence differences | The distinction between vendor telemetry and confirmed compromise received broader attention |
The dates are close together. Security teams reviewing older internal tickets should check whether their original conclusions were made before Alibaba clarified the affected range and Spring Boot packaging prerequisite. (NVD)
Why This Is a Java Supply Chain Problem
CVE-2026-16723 is not only a parser bug. It is also a dependency-governance problem.
Fastjson can reach a production process through paths that are invisible to the service owner:
Application
└── Internal platform SDK
└── Legacy integration library
└── com.alibaba:fastjson:1.2.83
The application’s pom.xml may not contain the word fastjson. A dependency-management platform may show it only several levels below a direct dependency. A vendor may shade Fastjson classes into another JAR, removing recognizable Maven coordinates. A Spring Boot build then packages the result under BOOT-INF/lib, where it becomes part of the runtime image.
The original Fastjson repository being archived increases the supply-chain significance. Alibaba’s repository points users toward Fastjson2, while the final Fastjson 1.x release remains inside the affected range. A team cannot solve this by waiting for Fastjson 1.2.84 unless the vendor announces a new maintenance direction. (GitHub)
Direct dependencies
These are easiest to find:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
Transitive dependencies
A business SDK may introduce Fastjson:
com.example:payment-sdk
\--- com.alibaba:fastjson:1.2.83
Removing imports from application code does not remove the runtime library.
BOM and dependency overrides
A parent POM or enterprise BOM may force a version different from the one developers expect. The dependency declaration in a module can therefore differ from the resolved version.
Shaded code
A library can copy Fastjson classes into its own namespace or embed them without standard Maven metadata. Ordinary coordinate matching may miss the copy.
Vendor products
Commercial Java products may contain Fastjson in a closed package. The customer may not have source access, build control, or permission to modify the application. The response then depends on vendor confirmation, compensating controls, network isolation, and upgrade availability.
Container images
A repository scan may inspect source code but not the final container. The image can contain:
- An older application JAR left in a backup directory.
- A diagnostic tool using Fastjson.
- Multiple application versions.
- An agent or extension installed during image construction.
- A vendor utility copied from another base image.
Serverless packages
A serverless deployment bundle can include Fastjson even when the service is not described as a traditional server. The relevant question remains whether the packaged runtime and classloader match the vulnerable environment.
Long-lived stored data
Supply-chain remediation usually focuses on code. Deserialization risk also attaches to data created under an old trust model. Stored JSON containing type metadata may remain in queues, databases, object stores, or caches after the library is replaced. Migration testing should include representative historical records.
Inventory the Resolved Dependency Graph
For Maven, inspect the resolved hierarchy rather than searching only the POM:
mvn -q dependency:tree \
-Dincludes=com.alibaba:fastjson
Apache Maven’s dependency plugin reports the resolved dependency tree and can expose the direct dependency that introduced Fastjson. (Apache Maven)
For Gradle:
./gradlew dependencyInsight \
--dependency fastjson \
--configuration runtimeClasspath
A broader view is available with:
./gradlew dependencies \
--configuration runtimeClasspath
Gradle’s dependencyInsight output is especially useful when version conflict resolution or a platform constraint selected an unexpected release. (Gradle Documentation)
Record:
- Requested version.
- Resolved version.
- Introducing dependency.
- Runtime configuration.
- Dependency constraint or BOM.
- Exclusions.
- Whether the library is still needed.
A source-tree result is only the beginning. The production artifact is the stronger evidence.
Inspect the Packaged Spring Boot Artifact
List Fastjson artifacts in the fat JAR:
unzip -l application.jar \
| grep -E 'BOOT-INF/lib/fastjson[^/]*\.jar'
Extract the nested dependency for offline inspection:
mkdir -p /tmp/fastjson-review
unzip -p application.jar \
BOOT-INF/lib/fastjson-1.2.83.jar \
> /tmp/fastjson-review/fastjson-1.2.83.jar
Read Maven metadata when present:
unzip -p /tmp/fastjson-review/fastjson-1.2.83.jar \
META-INF/maven/com.alibaba/fastjson/pom.properties
Expected metadata may resemble:
groupId=com.alibaba
artifactId=fastjson
version=1.2.83
Compute a hash for the evidence record:
sha256sum /tmp/fastjson-review/fastjson-1.2.83.jar
On macOS:
shasum -a 256 /tmp/fastjson-review/fastjson-1.2.83.jar
For a deployment directory:
find /app /opt /srv \
-type f \
-name 'fastjson*.jar' \
-print 2>/dev/null
A class-based check can find unshaded copies whose filenames were changed:
find . -type f -name '*.jar' -print0 |
while IFS= read -r -d '' jarfile; do
if jar tf "$jarfile" 2>/dev/null |
grep -q '^com/alibaba/fastjson/JSON.class$'; then
printf '%s\n' "$jarfile"
fi
done
This check does not detect relocated classes, and it does not assign a version. A shaded or modified copy may require software-composition tooling, bytecode signatures, vendor attestations, or manual comparison.
Do not delete or modify production artifacts while investigating. Work from a copied artifact whenever possible.
Build an Evidence Ladder
Vulnerability management becomes more reliable when each conclusion is tied to a level of evidence.
| Level | 증거 | 의미 |
|---|---|---|
| 1 | Fastjson appears in a source manifest | A developer intended to use the library |
| 2 | Maven or Gradle resolves 1.2.68 through 1.2.83 | The affected version is in a build dependency graph |
| 3 | The released artifact contains the affected library | The component reached a deployable package |
| 4 | The production process loads the affected library | Runtime exposure is established |
| 5 | The process uses a Spring Boot executable fat JAR | The documented packaging prerequisite is present |
| 6 | SafeMode is disabled or unverified | The primary mitigating control is absent |
| 7 | Untrusted JSON reaches a relevant parsing call | Parser reachability is established |
| 8 | An external or compromised actor can reach the input | A credible attack path exists |
| 9 | Suspicious parser, network, classloader, or process behavior is observed | Attempted or partial exploitation may have occurred |
| 10 | Attacker-directed code execution and follow-on activity are verified | A security incident is confirmed |
A team can prioritize remediation before reaching level 8. Levels 1 through 6 can be sufficient to justify enabling SafeMode because the control is explicit, vendor-recommended, and less expensive than proving every possible input route.
At the same time, incident declarations should not jump from level 2 directly to level 10. A dependency alert is not evidence that arbitrary code ran.
Trace Reachability From Input to Parser
Reachability review begins with call sites:
rg 'JSON\.parse(Object)?\(' src/
rg 'com\.alibaba\.fastjson' src/
rg 'ParserConfig' src/
These searches can miss reflection, wrappers, bytecode-generated code, and third-party libraries, but they provide a starting point.
Look for wrapper methods:
public final class JsonCodec {
public static <T> T decode(String body, Class<T> type) {
return JSON.parseObject(body, type);
}
}
A single wrapper can serve dozens of controllers and consumers. Review every trust boundary that supplies body.
For Spring applications, inspect:
- Controller parameters.
- Custom
HttpMessageConverterimplementations. - Request filters.
- WebFlux decoders.
- Webhook handlers.
- Exception-reporting endpoints.
- Administrative APIs.
- Multipart upload processors.
- Scheduled import jobs.
- Queue listeners.
- Cache deserialization.
- Redis serializers.
- Database JSON converters.
- RPC adapters.
- Third-party SDK callbacks.
A practical trace record can use the following fields:
| 필드 | 예 |
|---|---|
| Input source | Public webhook body |
| 인증 | HMAC signature |
| Verification order | Signature checked after parsing |
| Parser call | JsonCodec.decode |
| Fastjson method | JSON.parseObject |
| Target type | WebhookEnvelope |
| Dynamic fields | Map<String, Object> data |
| Maximum body size | 1 MB |
| SafeMode | Not configured |
| Runtime package | Spring Boot executable fat JAR |
| Network reachability | Public |
| Process egress | Unrestricted |
| Service identity | Cloud role with object-storage read access |
| 우선순위 | 중요 |
In this example, moving signature verification before parsing is useful, but it should accompany SafeMode or migration rather than replace it.
Authentication does not eliminate the vulnerability
An authenticated endpoint can still be attacked through:
- A low-privilege account.
- A compromised integration key.
- A multi-tenant customer.
- An internal service with excessive trust.
- A browser-based cross-origin flow.
- A separate SSRF vulnerability.
- A message producer controlled by another tenant.
Authentication changes who can reach the parser. It does not correct the parser’s trust decision.
Schema validation must occur before unsafe deserialization
A schema validator cannot protect a parser if the application first converts the body into a dynamic Java object and validates the result afterward.
Prefer:
Raw bytes
│
▼
Size and content-type limits
│
▼
Token-level or schema validation
│
▼
Fixed DTO deserialization
피하십시오:
Raw bytes
│
▼
Dynamic Java object construction
│
▼
Schema validation
Log the decision, not sensitive payloads
Reachability instrumentation can record:
- Route name.
- Parser implementation.
- Target DTO.
- Presence of forbidden type metadata.
- Rejection reason.
- Request identifier.
- Source identity or tenant.
- Body size.
It should not indiscriminately retain full request bodies containing passwords, tokens, health information, payment data, or personal information.
Safe PoC: Verify SafeMode Without Reproducing RCE
The safest useful proof of concept is a mitigation test, not a weaponized exploit.
The following lab verifies two properties:
- SafeMode rejects harmless JSON containing
@typemetadata. - Ordinary JSON bound to a fixed DTO still works.
The test does not contact a network service, fetch a remote JAR, load attacker-supplied bytecode, execute a command, write a file, scan a host, or reproduce the remote-code-execution chain. It should be run only in a local disposable project or authorized test environment.
Project structure
fastjson-safemode-lab/
├── pom.xml
└── src
└── main
└── java
└── lab
└── SafeModeCheck.java
Maven configuration
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>lab</groupId>
<artifactId>fastjson-safemode-lab</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.release>11</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
</dependencies>
</project>
The affected version is used only so the test reflects the configuration that defenders need to control. Do not expose this lab as a network service.
SafeMode verification code
package lab;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.parser.ParserConfig;
public final class SafeModeCheck {
public static final class OrderRequest {
public String item;
public int quantity;
}
public static final class AuditMarker {
public String note;
}
private SafeModeCheck() {
}
public static void main(String[] args) {
ParserConfig.getGlobalInstance().setSafeMode(true);
String harmlessTypeMetadata =
"{"
+ "\"@type\":\"lab.SafeModeCheck$AuditMarker\","
+ "\"note\":\"local mitigation test\""
+ "}";
boolean typeMetadataBlocked = false;
try {
JSON.parse(harmlessTypeMetadata);
} catch (JSONException expected) {
typeMetadataBlocked = true;
System.out.println(
"PASS: SafeMode rejected @type metadata."
);
}
if (!typeMetadataBlocked) {
throw new IllegalStateException(
"FAIL: @type metadata was not rejected."
);
}
String ordinaryJson =
"{\"item\":\"book\",\"quantity\":1}";
OrderRequest request = JSON.parseObject(
ordinaryJson,
OrderRequest.class
);
if (!"book".equals(request.item)
|| request.quantity != 1) {
throw new IllegalStateException(
"FAIL: ordinary DTO parsing did not behave as expected."
);
}
System.out.println(
"PASS: fixed DTO parsing still works."
);
}
}
Run the test
mvn -q dependency:build-classpath \
-Dmdep.outputFile=cp.txt
mvn -q compile
java -cp "target/classes:$(cat cp.txt)" \
lab.SafeModeCheck
Expected output:
PASS: SafeMode rejected @type metadata.
PASS: fixed DTO parsing still works.
On Windows, construct the classpath using the platform’s normal separator and shell syntax.
What the PoC proves
It proves that the local Fastjson process has SafeMode enabled through the explicit API call and that a representative fixed DTO still parses.
What the PoC does not prove
It does not prove:
- That every production instance has SafeMode enabled.
- That an environment variable reached the JVM.
- That every application parser uses the global configuration.
- That a shaded copy of Fastjson uses the same configuration.
- That no separate Fastjson 1.x copy exists.
- That historic malicious data is absent.
- That the host was never attacked.
- That migration testing is complete.
The same assertion should be moved into an integration or deployment test that exercises the actual application configuration.
Do not disable SafeMode and add remote resources merely to compare behavior. Reproducing code execution adds risk without improving the decision to patch.
Enable SafeMode Immediately
Alibaba documents three principal approaches.
JVM system property
java \
-Dfastjson.parser.safeMode=true \
-jar application.jar
For a systemd unit:
[Service]
ExecStart=/usr/bin/java \
-Dfastjson.parser.safeMode=true \
-jar /opt/application/application.jar
For Kubernetes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: application
spec:
template:
spec:
containers:
- name: application
image: registry.example/application@sha256:REPLACE_WITH_DIGEST
env:
- name: JAVA_TOOL_OPTIONS
value: "-Dfastjson.parser.safeMode=true"
The environment variable is not evidence by itself. Confirm that the JVM consumed it and that no wrapper script removed or replaced it.
Application code
import com.alibaba.fastjson.parser.ParserConfig;
public final class FastjsonSecurityConfiguration {
private FastjsonSecurityConfiguration() {
}
public static void apply() {
ParserConfig
.getGlobalInstance()
.setSafeMode(true);
}
}
Call the method before any untrusted JSON can be parsed. In applications with multiple classloaders or custom parser configurations, review whether every instance receives the setting.
Properties file
Create or update fastjson.properties:
fastjson.parser.safeMode=true
Ensure the file is placed where the running Fastjson version can load it. A configuration file present in the repository but missing from the final JAR does not mitigate production.
Alibaba recommends SafeMode as the fastest blocking control because it rejects all @type processing before the vulnerable path. (GitHub)
Verify the Runtime Setting
A common remediation failure occurs when a team updates deployment configuration but never proves that the running process received it.
Inspect the process arguments where permitted:
ps -ef | grep '[f]astjson.parser.safeMode'
With a suitable JDK tool available on the authorized host:
jcmd <PID> VM.system_properties \
| grep 'fastjson.parser.safeMode'
Check Kubernetes deployment output:
kubectl get deployment application -o yaml \
| grep -A2 -B2 'fastjson.parser.safeMode'
These checks prove different things:
- A manifest proves intended configuration.
- A pod specification proves generated workload configuration.
- JVM properties prove the running process received a property.
- The mitigation PoC proves Fastjson behavior.
- A production integration test proves the application path enforces the behavior.
Retain at least the final two forms of evidence.
If application code enables SafeMode directly, the JVM property may be absent. In that case, rely on a behavior-based test and code review rather than marking the control missing solely because the system property is not visible.

Consider the noneautotype Build
Alibaba identifies com.alibaba:fastjson:1.2.83_noneautotype as an immediate alternative. This artifact removes AutoType functionality at build time rather than relying on a runtime switch. (GitHub)
A Maven declaration looks like:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83_noneautotype</version>
</dependency>
A transitive dependency may require an exclusion:
<dependency>
<groupId>com.example</groupId>
<artifactId>legacy-sdk</artifactId>
<version>${legacy.sdk.version}</version>
<exclusions>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83_noneautotype</version>
</dependency>
Test the resolved graph afterward:
mvn -q dependency:tree \
-Dincludes=com.alibaba:fastjson
Then inspect the final fat JAR again. A dependency exclusion that works in one module may not remove a second copy introduced elsewhere.
The noneautotype build can break applications that deliberately depend on Fastjson type metadata. That compatibility problem should not be “solved” by restoring broad dynamic type resolution. Such applications need an explicit migration design with a narrow allowlist or application-owned type mapping.
Mitigation Options Compared
| 제어 | Security value | Main limitation | Recommended use |
|---|---|---|---|
| Enable SafeMode | Blocks @type handling before the vulnerable path | May break workflows that depend on dynamic type metadata | Immediate P0 control |
사용 1.2.83_noneautotype | Removes AutoType code from the artifact | Compatibility impact and continued reliance on archived 1.x code | Immediate alternative when tested |
| Migrate to Fastjson2 | Eliminates the root behavior identified by Alibaba | Requires compatibility and integration testing | Long-term correction |
| WAF or API gateway filtering | Can reduce obvious exploit traffic | Encoding, transformations, alternate paths, and false positives limit reliability | Temporary compensating control |
| Restrict outbound network access | Limits resource retrieval and command-and-control paths | Does not correct unsafe parsing and may not stop local effects | 심층 방어 |
| Run with least privilege | Limits post-execution blast radius | RCE within the service identity remains serious | Mandatory defense in depth |
| Remove weakly typed DTO fields | Reduces dynamic object construction | Does not replace the vendor mitigation | Architectural hardening |
| Authentication and signature checks | Reduces who can submit input | Credentials and internal paths may still be abused | Exposure reduction |
| Remove unused Fastjson dependency | Eliminates the component if genuinely unused | Shaded or duplicate copies may remain | Preferred when feasible |
WAF rules, egress restrictions, and authentication can reduce risk while a release is being prepared. They should never be recorded as equivalent to a library-level mitigation.
Detection Engineering
No single indicator proves exploitation. Detection should correlate request content, parser behavior, network activity, classloader events, and process actions.
HTTP and API telemetry
Potentially useful signals include:
- A JSON property named
@type. - Encoded variants such as
%40type. - Unexpected Java package or class names in JSON.
- JAR-related resource schemes.
- Nested archive references.
- Unusually long type identifiers.
- Requests that trigger repeated parser errors.
- A sudden increase in rejected JSON across unrelated endpoints.
A generic SIEM expression might be:
http.request.method = "POST"
AND http.request.body matches
/(?i)(@type|%40type|jar:(https?|file):)/
This is intentionally generic and must be adapted to the organization’s data model. It has important limitations:
- Request bodies may not be logged.
- A proxy may decompress, decode, normalize, or truncate content.
- Attackers may use transformations not represented by the expression.
- Legitimate legacy applications may use
@type. - Logging full bodies may violate privacy or compliance requirements.
- Asynchronous inputs may bypass HTTP logging entirely.
A safer production pattern is for the application or gateway to log a structured event when forbidden type metadata is detected, without retaining the complete payload.
Example event:
{
"event": "json_type_metadata_rejected",
"parser": "fastjson",
"route": "payment_webhook",
"request_id": "2d28f39f",
"authenticated": false,
"body_size": 842,
"source_category": "internet",
"action": "blocked"
}
애플리케이션 원격 분석
Monitor for:
- Fastjson
JSONExceptionevents involving type processing. - SafeMode rejection events.
- Class-not-found errors involving unexpected packages.
- Resource-loading exceptions.
- Nested-JAR resolution errors.
- Repeated parser failures from one source.
- Parsing behavior followed immediately by network or process activity.
Exception logging should preserve the request ID and route while avoiding untrusted payload reflection into logs. Raw attacker strings can cause log injection, excessive storage, or exposure of sensitive input.
Network telemetry
A Java service that normally communicates only with a database and an internal API should not suddenly initiate arbitrary outbound HTTP or DNS connections.
Useful signals include:
- New internet destinations contacted by the Java process.
- DNS requests for recently registered or low-reputation domains.
- Direct IP connections that bypass configured proxies.
- Requests for JAR or class-like content.
- Connections immediately following a parsing exception.
- Access to cloud metadata addresses.
- Connections from a namespace that normally has no egress.
Network telemetry is particularly valuable because public analyses connect the exploit path to resource resolution. It is still not sufficient alone: an outbound request can fail before code execution, and legitimate application behavior can also fetch remote resources. (ThreatBook)
Process telemetry
High-value indicators include:
java → sh
java → bash
java → cmd.exe
java → powershell.exe
java → curl
java → wget
java → python
java → chmod
These relationships are not universally malicious. Build servers, administrative tools, and document-processing applications may launch child processes legitimately. Baseline the service before writing a universal block rule.
More specific questions improve signal quality:
- Has this exact service image launched a shell before?
- Did the child process appear immediately after a suspicious request?
- Was the command line derived from external input?
- Did the process access secrets or persistence locations?
- Did it initiate a new outbound connection?
- Did it create an executable file?
Filesystem and container signals
Hunt for:
- New
.jar또는.classfiles in temporary directories. - Executables written by the Java process.
- Changes to startup scripts.
- Modified application JARs.
- New cron jobs or systemd units.
- Writes to mounted deployment directories.
- Access to Kubernetes service-account token paths.
- Reads of cloud credential files.
- Access to Docker or container-runtime sockets.
An attacker may execute entirely in memory, so the absence of new files does not prove safety.
Detection value and limitations
| 신호 | 가치 | Common false positives | Important limitation |
|---|---|---|---|
@type in JSON | Identifies type-metadata use | Legitimate legacy serialization | Can be encoded or hidden before the logging layer |
| JAR-related resource string | Closer to published technical behavior | Internal tooling and package APIs | Exact public strings may not represent every exploit variation |
| Fastjson type exception | Shows parser interaction | Broken clients and compatibility bugs | Exceptions do not prove successful exploitation |
| Java outbound network connection | Shows resource or command-and-control behavior | Normal API integrations | Destination context is required |
| Java child process | Stronger post-exploitation indicator | Report generation, media processing, admin tools | Fileless actions may not spawn a child |
| New JAR or class file | Possible payload staging | Hot deployment and plugin systems | Execution may occur without a persistent file |
| Cloud metadata access | Potential credential discovery | Some SDK initialization behavior | Network policy may block the final credential response |
| SafeMode rejection event | Confirms a blocked type-metadata attempt | Misconfigured legitimate client | Does not show whether earlier instances were vulnerable |
Threat Hunting After Exposure Is Confirmed
When an internet-reachable parser matches the affected conditions, remediation and hunting should proceed in parallel.
Preserve evidence before destructive changes
Collect where legally and operationally appropriate:
- Load balancer and reverse-proxy logs.
- API gateway logs.
- Application logs.
- DNS resolver logs.
- Egress proxy and firewall logs.
- EDR process trees.
- Container runtime events.
- Kubernetes audit logs.
- Cloud control-plane logs.
- Relevant object-storage and secret-access logs.
- A copy and hash of the deployed artifact.
- The image digest.
- JVM process arguments and environment.
- A list of loaded modules or JARs if available.
- Volatile evidence when an incident is strongly suspected.
A routine redeployment may destroy the container filesystem, process tree, temporary files, and memory evidence. The security team should balance containment against evidence preservation.
Correlate by time and request identity
A suspicious request becomes more meaningful when followed by:
- A Fastjson exception or type-resolution event.
- An outbound DNS or HTTP connection.
- A new Java child process.
- Access to credentials or metadata.
- A new session, token use, or internal lateral connection.
Use request IDs, trace IDs, pod names, process IDs, and timestamps. Clock synchronization matters. A two-minute skew between gateway and EDR logs can make a valid chain appear unrelated.
Review the process identity
Determine:
- Unix user or Windows service account.
- Container user and Linux capabilities.
- Kubernetes service account.
- Cloud IAM role.
- Mounted secrets.
- Database credentials.
- Filesystem permissions.
- Network policies.
- Accessible internal services.
Remote code execution with a constrained identity is different from host-root execution, but credentials available to the application can still produce serious cross-system impact.
Rotate exposed credentials based on evidence
Credential rotation may be appropriate when:
- The process accessed a credential after suspicious activity.
- The credential was readable by the compromised identity.
- The environment lacks sufficient logs to exclude access.
- A cloud role can mint new credentials.
- A token has broad or long-lived privileges.
Blindly rotating every enterprise credential can cause unnecessary disruption. Scope the action to the service’s actual access while recognizing that missing telemetry increases uncertainty.
Separate vulnerability remediation from incident closure
Enabling SafeMode prevents the documented parser path going forward. It does not remove persistence, revoke stolen tokens, repair modified data, or prove that earlier requests failed.
The closure record should contain two independent conclusions:
- The vulnerable condition has been remediated.
- The investigation found or did not find evidence of compromise, with stated limitations.
Migrate to Fastjson2
Alibaba states that Fastjson2 is not affected because the vulnerable root behavior was removed. The official project describes Fastjson2 as the successor to Fastjson 1.x and provides both a new core package and a compatibility module for applications that need a lower-friction transition. (GitHub)
Core Fastjson2 dependency
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${approved.fastjson2.version}</version>
</dependency>
Core APIs use the com.alibaba.fastjson2 package.
Compatibility module
The compatibility module uses the familiar artifact coordinates with a Fastjson2 release:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${approved.fastjson2.compat.version}</version>
</dependency>
Use a specific, organization-approved current release rather than an unbounded version range. The approved version should be checked against the official repository and release notes when the migration is performed.
Fastjson2 documentation warns that compatibility is not absolute. A successful compilation is therefore not proof of behavioral compatibility. (GitHub)
Migration test matrix
| 면적 | What to test | 실패 모드 |
|---|---|---|
| Field naming | camelCase, snake_case, aliases, acronyms | Fields silently remain unset |
| Unknown fields | Inputs containing additional properties | Requests fail or unexpected data is accepted |
| Numbers | Large integers, decimals, exponent notation | Precision loss or type changes |
| Dates and times | Time zones, epoch values, custom formats | Incorrect timestamps |
| Enums | Names, aliases, numeric values, unknown values | Deserialization failure or incorrect default |
| Null handling | Missing, explicit null, empty string | Different business behavior |
| Collections | Empty lists, generic maps, nested arrays | Type mismatch |
| Circular references | Existing serialized graphs | Output incompatibility |
| Custom serializers | Application-specific modules | Changed output or missing fields |
| Custom deserializers | Validation and mapping logic | Bypassed validation or runtime exceptions |
| Stored JSON | Database, queue, cache, and audit records | Old records cannot be read |
| Spring integration | Message converters and controller binding | Different parser selected at runtime |
| Error handling | Malformed and oversized input | Information leakage or denial of service |
| Security controls | Type metadata, SafeMode equivalent, allowlists | Reintroduction of dynamic type risk |
| Performance limits | Deep nesting and large documents | Resource exhaustion |
Do not casually enable SupportAutoType
Fastjson2 keeps AutoType disabled by default. Alibaba advises against explicitly enabling JSONReader.Feature.SupportAutoType broadly. If an application truly needs polymorphic input, use a strict allowlist handler and test every allowed type. (GitHub)
A safer application-owned mapping looks like:
public interface EventPayload {
}
public final class CreatedEvent implements EventPayload {
public String resourceId;
}
public final class DeletedEvent implements EventPayload {
public String resourceId;
}
public final class EventEnvelope {
public String eventType;
public String payloadJson;
}
Then map an external logical identifier to a fixed internal class:
public final class EventDecoder {
private EventDecoder() {
}
public static EventPayload decode(
String eventType,
String payloadJson) {
return switch (eventType) {
case "resource.created" ->
com.alibaba.fastjson2.JSON.parseObject(
payloadJson,
CreatedEvent.class
);
case "resource.deleted" ->
com.alibaba.fastjson2.JSON.parseObject(
payloadJson,
DeletedEvent.class
);
default ->
throw new IllegalArgumentException(
"Unsupported event type"
);
};
}
}
The external party controls resource.created, not a Java package name. The application owns the mapping and can review the finite set of allowed classes.
Test the packaged artifact after migration
Run the dependency checks again:
mvn -q dependency:tree \
-Dincludes=com.alibaba:fastjson,com.alibaba.fastjson2:fastjson2
Inspect the final fat JAR:
unzip -l application.jar \
| grep -Ei 'BOOT-INF/lib/.*fastjson'
The goal is to prove that no unintended Fastjson 1.x copy remains. A direct migration can succeed while a separate SDK continues to package 1.2.83 transitively.
Harden the Deserialization Boundary
CVE-2026-16723 belongs to the broader CWE-502 problem: untrusted data is deserialized into objects without sufficiently constraining what the data can cause the runtime to construct or invoke. MITRE and OWASP recommend avoiding native or type-rich deserialization across untrusted boundaries, using simpler data formats, and populating controlled application objects rather than allowing input to select arbitrary runtime types. (CWE)
Keep class names out of external protocols
Bad external contract:
{
"type": "com.example.internal.AdminAction",
"arguments": {
"operation": "..."
}
}
Safer external contract:
{
"action": "profile.update",
"arguments": {
"displayName": "Alice"
}
}
The server maps profile.update to a fixed handler after authorization and schema validation.
Replace dynamic containers
Instead of:
public Object payload;
prefer:
public ProfileUpdatePayload payload;
Instead of:
public Map<String, Object> attributes;
prefer:
public Map<String, String> labels;
or a defined class:
public final class AssetAttributes {
public String environment;
public String owner;
public String classification;
}
Validate size and depth
Even after eliminating the RCE path, an attacker may submit:
- Deeply nested arrays.
- Huge strings.
- Extremely large numeric values.
- Repeated keys.
- Large maps.
- Compressed request bodies that expand significantly.
Set limits at the proxy and application layers. Deserialization security includes resource consumption, not only code execution.
Authenticate before parsing when possible
Webhook signatures are frequently calculated over raw bytes. Verify the signature before performing rich object construction.
For authenticated APIs, reject invalid tokens and unauthorized tenants before deserializing large or complex bodies where the framework permits that ordering.
Restrict egress
A business service should have only the outbound destinations it needs. Use:
- Kubernetes NetworkPolicy.
- Cloud firewall rules.
- Service-mesh egress policies.
- Explicit proxies.
- DNS allowlists.
- Workload identity controls.
An egress restriction is not a parser fix, but it can block resource retrieval, credential exfiltration, and command-and-control traffic.
Use least privilege
Run the service:
- As a non-root user.
- With a read-only root filesystem where practical.
- Without the Docker socket.
- Without privileged container mode.
- Without unnecessary Linux capabilities.
- With a narrowly scoped cloud role.
- With a dedicated database account.
- Without write access to application binaries.
- Without shared administrative credentials.
Remove unused libraries
A library that is not loaded cannot expose its parser. Delete unused dependencies rather than carrying them because “another module may need them someday.”
Use dependency-analysis results carefully. Reflection can make a used dependency appear unused, so test the application before removal.
Improve the Software Supply Chain Control
An SBOM is useful when it represents the deployed artifact rather than only the source repository. CycloneDX tooling supports generation from common build ecosystems, but the document still needs to match the released image, nested dependencies, and repackaged components. (CycloneDX)
A stronger pipeline includes:
Resolve dependencies
│
▼
Build application
│
▼
Package Spring Boot fat JAR
│
▼
Generate SBOM from final artifact
│
▼
Scan nested dependencies
│
▼
Apply policy
│
▼
Run deserialization security tests
│
▼
Build container
│
▼
Generate or reconcile image SBOM
│
▼
Sign artifact and image
│
▼
Deploy by digest
Policy should distinguish:
- Fastjson 1.x absent.
- Fastjson 1.x present but not in the affected range.
- Fastjson 1.2.68 through 1.2.83 with SafeMode unproven.
1.2.83_noneautotype.- Fastjson2.
- Shaded code with unknown provenance.
- Vendor software awaiting an advisory.
A VEX statement can communicate that a component is not affected because the deployment prerequisite is absent or SafeMode is enforced. Such a statement should include evidence and an expiration condition. A future packaging change can invalidate the conclusion.
예를 들어
component: com.alibaba:fastjson:1.2.83
vulnerability: CVE-2026-16723
status: not_affected
justification: vulnerable_code_cannot_be_controlled_by_adversary
evidence:
- runtime artifact is not a Spring Boot executable fat JAR
- production launch method uses external Tomcat WAR deployment
validated_at: 2026-07-27
revalidate_when:
- packaging changes
- application server changes
- Fastjson configuration changes
- vendor advisory changes
The exact VEX format should follow the organization’s selected standard. The important property is that the justification is testable and tied to the released artifact.
Evidence-Driven Validation Instead of Alert Inflation
A high-quality validation workflow connects five forms of proof:
- Component proof — the affected Fastjson version exists in the runtime artifact.
- Deployment proof — the application uses the documented Spring Boot executable fat-JAR model.
- Configuration proof — SafeMode is disabled, enabled, or unknown.
- Reachability proof — attacker-controlled JSON reaches a relevant parser.
- Remediation proof — the released artifact and running process enforce the selected control.
Automation can correlate these records across many services, but it must preserve the distinction between “component detected” and “RCE verified.” AI-assisted testing is most useful when it organizes build evidence, runtime configuration, parser paths, endpoint reachability, and retest artifacts rather than generating an unsupported exploitability verdict.
Teams building such evidence chains can use an automated security-testing workflow such as 펜리전트 to coordinate asset discovery, validation steps, evidence capture, and remediation retesting. Its analysis of CVE-2026-12569 and untrusted deserialization risk provides a related example of separating vulnerable-code presence, exposure conditions, mitigations, and compromise evidence. Those workflows still depend on Alibaba’s advisory and the actual application artifact as the authority for CVE-2026-16723. (펜리전트)
Related Fastjson Vulnerabilities
CVE-2026-16723 is easier to understand when compared with earlier Fastjson issues.
| CVE | 영향을 받는 범위 | Core condition | Main mitigation lesson |
|---|---|---|---|
| CVE-2017-18349 | Fastjson before 1.2.25 | Crafted JSON could trigger unsafe type-driven deserialization in vulnerable environments | Untrusted input must not control Java runtime types |
| CVE-2022-25845 | Fastjson before 1.2.83 | AutoType security restrictions could be bypassed under specific conditions, with exploitation depending on additional target properties | A denylist or disabled-by-default switch can fail when alternative resolution paths exist |
| CVE-2026-16723 | Fastjson 1.2.68 through 1.2.83 | Default AutoType-off configuration remains vulnerable in the documented Spring Boot executable fat-JAR environment when SafeMode is off | SafeMode or code removal is required; migration to Fastjson2 is the durable direction |
CVE-2017-18349
The NVD description for CVE-2017-18349 covers Fastjson releases before 1.2.25 and describes crafted JSON leading to remote code execution in vulnerable application conditions. The issue belongs to the earlier pattern in which an attacker influenced type construction and relied on dangerous classes available to the application. (NVD)
Its continuing relevance is architectural. A JSON parser should not accept arbitrary Java implementation names from an external client. Fixing one denylist entry or gadget does not correct that protocol design.
CVE-2022-25845
CVE-2022-25845 affected Fastjson before 1.2.83 and involved a bypass of AutoType-related security checks under particular conditions. JFrog’s analysis emphasized that successful RCE was not automatic: it required target-specific research and an appropriate exploitation path. Fastjson 1.2.83 was the important upgrade for that issue. (NVD)
CVE-2026-16723 demonstrates why “we upgraded to 1.2.83” is no longer a complete statement. Version 1.2.83 fixed the earlier vulnerability but is included in the new affected range.
The broader lesson
Security controls age in layers:
- A vulnerable gadget is blocked.
- A denylist is expanded.
- AutoType defaults change.
- A SafeMode is introduced.
- A new resolution path bypasses an older assumption.
- The library generation is replaced.
The durable control is not an endless collection of blocked class names. It is preventing untrusted input from directing runtime type selection and moving to an implementation whose design does not contain the vulnerable behavior.
A Hypothetical Enterprise Case
Consider a fictional order-processing service called order-webhook.
The development team does not declare Fastjson directly. It depends on an internal partner SDK:
order-webhook
└── partner-integration-sdk
└── fastjson 1.2.83
The service is built with Spring Boot and deployed as:
java -jar order-webhook.jar
Inspection shows:
BOOT-INF/lib/fastjson-1.2.83.jar
The public webhook accepts:
public final class PartnerEvent {
public String eventType;
public Map<String, Object> data;
}
The body is parsed before signature verification:
PartnerEvent event =
JSON.parseObject(body, PartnerEvent.class);
signatureVerifier.verify(body, signature);
SafeMode is not configured. The container runs as a non-root user, but it has unrestricted internet access and a cloud role that can read an order archive.
Initial alert
The SCA platform reports CVE-2026-16723. That alone proves only the resolved component version.
Deployment validation
The team inspects the release artifact and confirms the Spring Boot fat-JAR structure. The deployment command uses java -jar. The package prerequisite is now established.
Configuration validation
No JVM property, properties file, or startup code enables SafeMode. The primary mitigation is absent.
Reachability validation
The webhook accepts attacker-controlled JSON before validating the signature. The DTO contains Map<String, Object>. A relevant parser path is reachable without a trusted sender.
The team now has a high-confidence exposure finding without executing a malicious payload.
Immediate containment
The operations team:
- Enables
-Dfastjson.parser.safeMode=true. - Restricts egress to the known partner API and required internal services.
- Moves signature verification before JSON deserialization.
- Adds a request-size limit.
- Deploys the change by image digest.
- Runs the local SafeMode regression assertion through the actual application path.
- Preserves recent gateway, DNS, process, and cloud-access logs.
Investigation
Analysts search for:
@typemetadata in retained request telemetry.- Java process connections to unexpected domains.
- Child processes spawned by the application.
- Access to cloud credentials or the order archive.
- New files in writable container paths.
- Suspicious requests followed by application restarts.
They find several requests containing type-like metadata, but no associated outbound connection, child process, credential access, or file creation. The final incident statement says that attempted probing was observed but successful code execution was not established within the available telemetry window.
Permanent correction
The development team excludes Fastjson from the SDK and migrates the integration layer to Fastjson2. It replaces Map<String, Object> with explicit event DTOs and preserves SafeMode until Fastjson 1.x is absent from the final artifact.
The final evidence package contains:
- Old and new dependency trees.
- Old and new JAR inventories.
- Image digests.
- SafeMode test output.
- Updated signature-verification order.
- Egress-policy change.
- Fastjson2 compatibility test results.
- Threat-hunting scope and limitations.
This is a defensible vulnerability response. It neither dismisses the SCA alert nor mislabels component presence as confirmed compromise.
일반적인 실수
Assuming AutoType disabled means safe
For CVE-2026-16723, Alibaba explicitly says the vulnerable path works under the default AutoType-off configuration. SafeMode is the relevant emergency control. (GitHub)
Treating every Fastjson finding as confirmed RCE
The official chain depends on a specific version range, Spring Boot executable fat-JAR packaging, SafeMode being off, and attacker-controlled input reaching Fastjson.
Searching only source manifests
Fastjson may be transitive, shaded, repackaged, or introduced during image creation. Inspect the resolved graph and final runtime artifact.
Downgrading below 1.2.68
The official affected range begins at 1.2.68, but older Fastjson releases contain historic vulnerabilities. Downgrading to unsupported code is not a safe migration plan.
Believing 1.2.83 is universally safe
Version 1.2.83 addressed CVE-2022-25845 but is affected by CVE-2026-16723. Security decisions must reference the specific CVE and deployment state.
Relying on a fixed top-level DTO
A DTO with 개체, 지도, interface, abstract-class, or generic extension fields can preserve dynamic type behavior.
Using WAF filtering as the final fix
A WAF may reduce obvious payloads but cannot guarantee coverage across encoding, alternate content types, asynchronous consumers, stored JSON, and internal entry points.
Recording a configuration change without runtime proof
A Helm value, environment variable, or systemd file does not prove the process received the setting. Verify behavior in the deployed release.
Ignoring internal services
An internal parser may be reachable through compromised workloads, SSRF, shared queues, low-privilege users, or stolen service credentials.
Closing the incident after enabling SafeMode
SafeMode prevents the documented future path. It does not prove that earlier exploitation failed or remove post-exploitation persistence.
Re-enabling broad AutoType after migration
Fastjson2 is unaffected under its safer design and defaults. Explicitly enabling broad AutoType can recreate an unnecessary class-selection risk even when it does not recreate this exact CVE.
Prioritization Matrix
| Conditions | 우선순위 | Recommended decision |
|---|---|---|
| Affected version, Spring Boot fat JAR, SafeMode off, public unauthenticated JSON path | 중요 | Mitigate immediately, preserve logs, and hunt for exploitation |
| Affected version, fat JAR, SafeMode off, authenticated low-privilege API | Critical or high | Mitigate immediately and review account abuse paths |
| Affected version, fat JAR, SafeMode off, internal message consumer | 높음 | Apply mitigation and evaluate producer trust and lateral reachability |
| Affected version, fat JAR, SafeMode unknown | 높음 | Treat unknown as unmitigated until proven otherwise |
| Affected version, SafeMode verified true | Medium migration priority | Preserve evidence and remove Fastjson 1.x through planned migration |
1.2.83_noneautotype verified in runtime | Medium migration priority | Test compatibility and move toward Fastjson2 |
| Fastjson2 only | Not affected by this CVE | Continue ordinary parser and dependency hygiene |
| Non-Spring-Boot WAR verified | Lower priority for this CVE | Document evidence and review other Fastjson risks |
| Source dependency only, absent from release | Not a production exposure | Fix build hygiene and ensure future releases remain clean |
| Shaded version unknown | High until resolved | Obtain provenance or replace the component |
Priority also depends on process privilege. A public parser running with cloud-administrator credentials deserves a faster incident response than a constrained offline utility, even if both match the same CVSS record.
자주 묻는 질문
Does CVE-2026-16723 affect every application using Fastjson?
- No. Alibaba identifies Fastjson 1.2.68 through 1.2.83 as the affected version range.
- The documented chain requires a Spring Boot executable fat JAR launched with
java -jar. - SafeMode must be off.
- Attacker-controlled JSON must reach a relevant Fastjson parsing path.
- Plain non-Spring-Boot JARs, generic uber-JARs, and Tomcat or Jetty WAR deployments are listed as unaffected by this specific chain.
- Older or differently packaged Fastjson applications may still have other deserialization risks.
- Verify the released runtime artifact rather than relying only on source manifests. (GitHub)
Is CVE-2026-16723 exploitable when AutoType is disabled?
- Yes, under the other documented conditions.
- The official advisory states that the chain works with AutoType disabled and SafeMode disabled.
setAutoTypeSupport(false)is therefore not sufficient evidence of remediation.- SafeMode blocks all
@typehandling before the vulnerable path. - Applications should enable SafeMode immediately or use the noneautotype build while planning migration. (GitHub)
Is Fastjson 1.2.83 safe?
- Not for CVE-2026-16723 in the documented vulnerable deployment.
- Fastjson 1.2.83 fixed the earlier CVE-2022-25845 issue, but it is included in the affected range for CVE-2026-16723.
- There is no newly patched Fastjson 1.x release identified in Alibaba’s advisory.
1.2.83_noneautotypeis a separate build that removes AutoType functionality and is recommended as an immediate option.- Fastjson2 is the long-term migration target. (GitHub)
How can I tell whether my application is a Spring Boot executable fat JAR?
- 실행
unzip -l application.jarand look forBOOT-INF/classes그리고BOOT-INF/lib. - Inspect
META-INF/MANIFEST.MFfor a Spring Boot launcher andStart-Class. - Confirm the production command actually uses
java -jar. - Inspect the deployed artifact or container image, not only the local build output.
- Record the artifact hash or image digest so the conclusion is tied to a specific release.
- A file named
.jaris not enough to establish the prerequisite; its structure and launcher behavior matter. (홈)
Does parsing into a fixed Java class prevent the vulnerability?
- Not automatically.
- Alibaba warns that fixed target-class parsing remains risky when the DTO contains
개체,지도, or other dynamic fields. - Review the complete object graph, not only the top-level class.
- Replace weakly typed fields with explicit DTOs whenever possible.
- Use schema validation before deserialization.
- Enable SafeMode or remove the affected library even after strengthening DTOs. (GitHub)
What is the difference between SafeMode, noneautotype, and Fastjson2?
- SafeMode is a Fastjson 1.x runtime control that rejects all
@typeprocessing before the vulnerable path. 1.2.83_noneautotypeis a Fastjson 1.x build with AutoType functionality removed at compile time.- Fastjson2 is the successor library and is listed by Alibaba as unaffected by CVE-2026-16723.
- SafeMode is usually the fastest emergency control.
- The noneautotype build provides stronger code removal but can cause compatibility problems.
- Fastjson2 is the preferred long-term direction and requires regression testing.
- Broad AutoType support should not be re-enabled during migration. (GitHub)
Has exploitation been confirmed in the wild?
- ThreatBook and Imperva reported exploitation activity or attack attempts.
- Public summaries did not provide enough raw evidence to verify the success rate or establish widespread compromise independently.
- The NVD record published on July 23 displayed CISA-ADP exploitation status as
없음. - The Hacker News reported that the CVE was not in CISA’s KEV catalog on July 25.
- These sources may be applying different standards to attempted exploitation and confirmed successful compromise.
- Defenders should hunt for suspicious activity without overstating unverified incident counts.
- Absence from KEV at a particular date is not a reason to delay SafeMode or migration. (NVD)
What evidence should a security team retain to prove remediation?
- The resolved Maven or Gradle dependency tree.
- A listing and hash of the final JAR or container image.
- Proof of the deployment model and startup command.
- Proof that SafeMode is active in the running process.
- Output from a behavior-based SafeMode regression test.
- Evidence that Fastjson 1.x is absent after migration.
- Route and code evidence showing how untrusted JSON is validated.
- Updated SBOM or VEX data tied to the released artifact.
- Egress-policy and least-privilege controls.
- Threat-hunting scope, findings, dates, and telemetry limitations.
- A retest after the production deployment, not only after a local build.
Closing Assessment
CVE-2026-16723 is severe because a default Fastjson security assumption no longer holds in the affected Spring Boot packaging environment. AutoType being disabled is not enough, and Fastjson 1.2.83 is not a fixed release for this issue.
The response should still remain precise. A vulnerable dependency does not by itself prove remote code execution. Teams must establish the runtime version, executable-JAR structure, SafeMode state, untrusted input path, external reachability, and service privileges.
SafeMode is the immediate control. The noneautotype build is an additional short-term option. Fastjson2 migration, explicit DTOs, controlled type mappings, restricted egress, and least-privilege execution provide the durable correction.
The strongest closure statement is not “the scanner is green.” It is a reproducible evidence chain showing that the vulnerable component or behavior is absent from the deployed artifact, the parser rejects external type metadata, and the production application remains functional after the change.

