java.rmi.security.server-dangerous-class-deserialization.server-dangerous-class-deserialization

profile photo of semgrepsemgrep
Author
5,552
Download Count*

Using a non-primitive class with Java RMI may be an insecure deserialization vulnerability. Depending on the underlying implementation. This object could be manipulated by a malicious actor allowing them to execute code on your system. Instead, use an integer ID to look up your object, or consider alternative serialization schemes such as JSON.

Run Locally

Run in CI

Defintion

rules:
  - id: server-dangerous-class-deserialization
    severity: WARNING
    languages:
      - java
    metadata:
      cwe:
        - "CWE-502: Deserialization of Untrusted Data"
      owasp:
        - A08:2017 - Insecure Deserialization
        - A08:2021 - Software and Data Integrity Failures
      references:
        - https://mogwailabs.de/blog/2019/03/attacking-java-rmi-services-after-jep-290/
      category: security
      technology:
        - rmi
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - audit
      likelihood: LOW
      impact: HIGH
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - "Insecure Deserialization "
    message: Using a non-primitive class with Java RMI may be an insecure
      deserialization vulnerability. Depending on the underlying implementation.
      This object could be manipulated by a malicious actor allowing them to
      execute code on your system. Instead, use an integer ID to look up your
      object, or consider alternative serialization schemes such as JSON.
    patterns:
      - pattern: |
          interface $INTERFACE extends Remote {
            $RETURNTYPE $METHOD($CLASS $PARAM) throws RemoteException;
          }
      - metavariable-regex:
          metavariable: $CLASS
          regex: (?!int|boolean|short|long|byte|char|float|double)

Examples

server-dangerous-class-deserialization.java

// cf. https://mogwailabs.de/blog/2019/03/attacking-java-rmi-services-after-jep-290/

package de.mogwailabs.BSidesRMIService;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

import java.rmi.Remote;
import java.rmi.RemoteException;

// ruleid:server-dangerous-class-deserialization
public interface IBSidesService extends Remote {
   boolean registerTicket(String ticketID) throws RemoteException;
   void vistTalk(String talkname) throws RemoteException;
   void poke(Attendee attende) throws RemoteException;
}

// ok:server-dangerous-class-deserialization
public interface IBSidesServiceOK extends Remote {
   boolean registerTicket(long ticketID) throws RemoteException;
   void vistTalk(long talkID) throws RemoteException;
   void poke(int attende) throws RemoteException;
}

public class Attendee {
    public int id;
    public String handle;
}

public class BSidesServer {
    public static void main(String[] args) {
        try {
            // Create new RMI registry to which we can register
            LocateRegistry.createRegistry(1099);

            // Make our BSides Server object
            // available under the name "bsides"
            Naming.bind("bsides", new BSidesServiceServerImpl());
            System.out.println("BSides RMI server is ready");

        } catch (Exception e) {
            // In case of an error, print the stacktrace
            // and bail out
            e.printStackTrace();
        }
    }
}