[SECURITY] Java deserialization of `type=serializable` REST variables (CVSS 8.0), unsandboxed deployable artifacts, order-column SQLi, HTTP-task SSRF
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 25/100
Hướng nghiên cứu
Bắt đầu bằng cách lần theo luồng của flowable-rest đối với multipart serializable variables, deployment artifacts, thứ tự của management tables và cách xử lý requestUrl của HTTP service tasks, sử dụng các REST endpoints được liệt kê và các hành vi đã quan sát làm điểm tái hiện. Công việc được xem là hoàn tất khi các maintainer thống nhất về các bản sửa lỗi trong phạm vi xác định cho cả bốn findings và mỗi hành vi đều có kiểm thử hồi quy; phối hợp việc disclosure riêng.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Consolidated to avoid flooding the tracker — happy to split on request. All findings verified dynamically by the reporter on the standard flowable-rest deployment (2026-09-02/03).
Finding 1 — Unrestricted deserialization of type=serializable variables (High)
Summary. The REST API accepts multipart variables of type=serializable; the raw bytes pass through ObjectInputStream.readObject() on the engine host with no class allow-list. We confirmed readObject executes and reconstructs attacker-supplied objects. The shipped -Djdk.serialFilter=maxarray=...;maxdepth=... bounds graph size only — gadget classes on the engine classpath remain viable.
Affected: flowable-engine @ 1663e588179d (flowable-app-rest module), standard flowable-rest deployment.
CVSS v3.1 (self-assessed): 8.0 — AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H (AC:H for gadget dependency; demo deployments with published credentials raise this materially).
Attack Path
Step 1: POST /runtime/tasks (create a task; any assignee)
Step 2: POST /runtime/tasks/{taskId}/variables (multipart)
name=serV1 type=serializable scope=local
file=@<serialized Java object bytes>
→ stored, then read through ObjectInputStream on read-back
Step 3: GET /runtime/tasks/{taskId}/variables/serV1
→ server has executed readObject() and reconstructs the object
(Same sink on /runtime/executions/{id}/variables and /runtime/process-instances/{id}/variables.)
Prerequisites: REST API credentials. The official sample deployments ship well-known demo credentials (rest-admin), which makes this effectively unauthenticated RCE surface there.
Proof of Concept (executed). Uploading a serialized java.util.Date (epoch 1700000000000) returned:
HTTP 201 {"name":"serV1","scope":"local","type":"date","value":"2023-11-14T22:13:20Z"}
The server executed readObject() and recognized the attacker-supplied object as a Date, echoing its value — arbitrary bytes are deserialized server-side; a GET returns the same reconstructed value.
Impact. With any gadget present in the engine's large dependency surface: full RCE. Without: unexpected object construction side effects and resource exhaustion.
Suggested fix. Reject type=serializable on REST input (keep JSON-friendly types; opaque binary otherwise) and add a strict class allow-list jdk.serialFilter for any path that must deserialize.
Finding 2 — Deployable process artifacts execute without a sandbox (High as deployed)
Summary. These are designed extension points; the risk is that no expression/script sandbox or allow-list exists and the REST demo profile makes deployment a single authenticated request. All of the following were executed on the engine host:
| Artifact | Result (observed) |
|---|---|
serviceTask flowable:type="shell" (command=echo) |
OS command executed; stdout returned as process variable (out=SH_RCE_OK) |
<scriptTask> (JSR-223) |
script evaluated (execution.setVariable("sv","SCRIPT_1337")) |
serviceTask flowable:class="java.lang.Thread" |
class loaded + instantiated (type-check error proves Class.forName) |
flowable:expression="${1337+10}" (BPMN), DMN outputEntry ${1337+10}, CMMN + Event Registry delegate expressions |
JUEL evaluated (1347 returned in returnVariables) |
Suggested fix. Provide an opt-in sandbox profile for deployments where engine admins are not OS-trusted: disabled shell tasks by config, restricted ScriptEngine lookup, blocked type resolution in expressions.
Finding 3 — orderAscendingColumn / orderDescendingColumn SQL injection (Medium)
GET /management/tables/{table}/data?orderAscendingColumn=ID_' → HTTP 500 with a raw H2 driver syntax error; ordering by KEY_ vs NAME_ yields different result orders — a workable error/boolean-based injection over the authenticated management API.
Suggested fix: validate the column identifier against the table's actual columns; never interpolate the raw parameter.
Finding 4 — HTTP service task requestUrl expression SSRF (Medium)
A deployed HTTP service task whose requestUrl resolves from a process variable makes the engine issue a GET to an arbitrary URL at process start. Verified: a loopback listener captured the engine's GET /V27_SSRF. Combined with Finding 2's deployment path this is an internal-network probing primitive.
Suggested fix: URL validation / egress policy for HTTP tasks.
All steps executed by the reporter against a live deployment. AI tools were used to help discover and prepare these findings. Reported 2026-09-07; suggesting a 90-day coordinated disclosure window — happy to coordinate on GHSA/CVE.
- 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
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của flowable/flowable-engine
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
flowable/flowable-engine#4268 ·
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 30/100
flowable/flowable-engine#4293 ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
flowable/flowable-engine#4292 ·
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 30/100
flowable/flowable-engine#4291 ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
flowable/flowable-engine#4290 ·
Tất cả issue của flowable/flowable-engine
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
Maintainer thường phản hồi trong vòng 1 ngày
-
go 🏃 testing 🧪
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
valkey-io/valkey-glide#7239 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
github/copilot-sdk#2793 ·
Maintainer thường phản hồi trong vòng 1 ngày