CVE-2025-15222
Executive Summary
CVE-2025-15222 is a critical deserialization vulnerability in Dromara Sa-Token up to version 1.44.0. The flaw resides in the SaSerializerTemplateForJdkUseBase64.java file, where the ObjectInputStream.readObject method is invoked without proper validation. This allows an attacker to execute arbitrary code remotely by sending a crafted serialized object. The attack complexity is high, but a public proof-of-concept (PoC) exists, making exploitation feasible for skilled adversaries. The vendor has not responded to disclosure attempts, leaving the vulnerability unpatched. This report provides a comprehensive technical analysis, detection rules, and mitigation strategies.
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
Sa-Token is a Java-based authentication and authorization framework widely used in enterprise applications. The vulnerability affects the core serialization component, which is often included as a transitive dependency. Organizations using Sa-Token in their supply chain should treat this as a high-priority risk, as no official patch is available. Immediate mitigation steps are required.
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: 5.0 (Medium)
- Attack Vector: Network (AV:N)
- Attack Complexity: High (AC:H) – requires specific conditions and crafted payloads.
- Privileges Required: None (PR:N)
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U)
- Confidentiality Impact: High (C:H)
- Integrity Impact: High (I:H)
- Availability Impact: High (A:H)
Despite the medium base score, the high impact on confidentiality, integrity, and availability, combined with a public PoC, elevates the real-world threat level to Critical.
Deep Dive & Mechanics
The vulnerability is a classic Java deserialization flaw. The SaSerializerTemplateForJdkUseBase64 class uses ObjectInputStream.readObject() to deserialize data from a Base64-encoded string. If an attacker can control the serialized data, they can craft a malicious object that, when deserialized, executes arbitrary code. This is typically achieved using gadget chains from libraries like Commons Collections or Spring.
The attack flow:
- Attacker crafts a malicious serialized Java object using a known gadget chain.
- The object is Base64-encoded and sent to the vulnerable endpoint.
- The server decodes the Base64 string and passes it to
ObjectInputStream.readObject(). - During deserialization, the gadget chain triggers arbitrary code execution.
The high complexity stems from the need to identify a valid gadget chain in the target's classpath and bypass any existing security filters.
Vulnerable vs. Patched Code
Vulnerable Code (Sa-Token <= 1.44.0):
public class SaSerializerTemplateForJdkUseBase64 {
public static Object deserialize(String data) {
byte[] bytes = Base64.getDecoder().decode(data);
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject(); // Unsafe deserialization
}
}
Patched Code (Hypothetical):
public class SaSerializerTemplateForJdkUseBase64 {
public static Object deserialize(String data) {
byte[] bytes = Base64.getDecoder().decode(data);
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
// Use a safe deserialization library or validate input
// Example: Use a whitelist of allowed classes
ValidatingObjectInputStream ois = new ValidatingObjectInputStream(bis);
ois.accept(AllowedClasses.class); // Only allow specific classes
return ois.readObject();
}
}
The patched version would implement class whitelisting or use a safe deserialization library like Apache Commons IO's ValidatingObjectInputStream.
Exploitation & Lab Setup
Red Team
Prerequisites:
- Java Runtime Environment (JRE) 8 or later.
- ysoserial tool for generating gadget chains.
- A vulnerable Sa-Token instance (version <= 1.44.0).
Exploitation Steps:
- Identify a gadget chain available in the target's classpath (e.g., CommonsCollections1).
- Generate a malicious payload:
java -jar ysoserial.jar CommonsCollections1 'calc.exe' > payload.bin - Base64-encode the payload:
base64 -w0 payload.bin > payload.b64 - Send the payload to the vulnerable endpoint (e.g., via HTTP POST):
curl -X POST -d "data=$(cat payload.b64)" http://target.com/vulnerable-endpoint
Expected Outcome: The target executes the command (e.g., launches calculator on Windows or runs a reverse shell).
Blue Team
Detection & Response:
- Monitor for Base64-encoded payloads in HTTP requests.
- Use network segmentation to limit exposure of Sa-Token services.
- Deploy Web Application Firewall (WAF) rules to block suspicious serialized objects.
- Enable Java security manager with a custom policy to restrict deserialization.
Honeypot Setup:
- Deploy a decoy Sa-Token instance to capture attacker payloads.
- Analyze captured payloads to identify gadget chains and attacker TTPs.
Indicators of Compromise (IOCs)
- Network IOCs:
- HTTP requests containing large Base64-encoded strings in parameters like
data,token, orsession. - Outbound connections to attacker-controlled IPs on common ports (e.g., 4444 for reverse shells).
- HTTP requests containing large Base64-encoded strings in parameters like
- File IOCs:
- Unexpected files in temporary directories (e.g.,
/tmp/exploit). - Modified Java class files or JARs.
- Unexpected files in temporary directories (e.g.,
- Process IOCs:
- Unusual Java processes executing commands like
calc.exe,bash -i, orpowershell. - Spawned child processes from the Java runtime.
- Unusual Java processes executing commands like
Detection Engineering
YARA Rule
rule CVE_2025_15222_Deserialization {
meta:
description = "Detects malicious serialized Java objects targeting CVE-2025-15222"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-15222"
strings:
$base64_pattern = /[A-Za-z0-9+/]{50,}={0,2}/ // Base64 encoded data
$java_magic = { AC ED 00 05 } // Java serialization magic bytes
$gadget_chain = /commons-collections|spring|javassist/ // Common gadget chains
condition:
$java_magic at 0 and $base64_pattern and $gadget_chain
}
Sigma Rule
title: CVE-2025-15222 Deserialization Attempt
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects HTTP requests with Base64-encoded Java serialized objects
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: 'data='
cs-uri-query|re: '([A-Za-z0-9+/]{50,}={0,2})'
condition: selection
falsepositives:
- Legitimate Base64 data in requests
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-15222 Deserialization Attempt"; flow:to_server; content:"POST"; http_method; content:"data="; http_uri; pcre:"/([A-Za-z0-9+/]{50,}={0,2})/"; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the vulnerable deserialization endpoint if not required.
- Implement input validation to reject suspicious Base64-encoded payloads.
- Apply network segmentation to limit access to Sa-Token services.
Long-term Fixes:
- Upgrade to a patched version once available (monitor vendor for updates).
- Replace
ObjectInputStreamwith a safe deserialization library (e.g., Apache Commons IOValidatingObjectInputStream). - Implement a custom deserialization filter using
ObjectInputFilter(Java 9+).
Compensating Controls:
- Deploy a WAF with rules to block known gadget chain patterns.
- Use runtime application self-protection (RASP) tools to detect deserialization attacks.
- Conduct regular security audits and penetration testing.
Valters IT
Securing Digital Frontiers