← Back to all reports

Cross-Tenant Team Takeover: Guest Admin Evicts the Owner and Destroys the Team

Reported Apr 29, 2026
Severity High
Platform Web / API
Vulnerability Class Privilege Escalation (CWE-269)
Target Type Enterprise SaaS / Digital Adoption
Impact Permanent team destruction across tenant boundary

The Risk

If a customer invited an outside collaborator from a different company to a single project, that outside collaborator could kick the customer out of their own project and permanently delete it. The customer's most senior administrator could not stop this and could not get the project back. A compromised contractor account or a departing employee with project-admin rights could destroy customer projects in seconds, with no recovery and no notification to the owners.

The Vulnerability

Two destructive team-management endpoints, POST /team/user/remove and DELETE /team/{teamId}, gated only on a single check: "does the caller have the team-level ADMIN role?". They did not enforce a role hierarchy, did not flag the team's creator as protected, and ignored the caller's account-level role on the team's home tenant.

The platform supported inviting an external user from a completely different customer tenant into a single team as a team admin. That guest team admin then sat at the same role level as the team's original creator (also a team admin, plus a tenant-level senior administrator). When two admins of equal rank existed, either could remove the other. The guest could remove the owner.

The Attack

Setup

Two test accounts on different domains were registered, landing on two separate tenants. The victim account became a team creator and a tenant-level senior administrator. The attacker account had no prior relationship with the victim's tenant.

Step 1, the legitimate cross-tenant invitation

  1. The victim created a team and uploaded a document to it.
  2. The victim sent the attacker a cross-tenant invitation as team admin (a supported flow).
  3. The attacker accepted the invitation. The attacker now had team admin role on a team in the victim's tenant, with no other relationship to that tenant.

Step 2, the attacker removes the team creator

POST /team/user/remove
Authorization: Bearer <attacker token>

{"teamId": "<team id>", "sub": "<victim user id>"}

Response: 201 {"success": true}. The victim was silently removed from the team. No notification, no role-hierarchy check, no creator protection. A follow-up GET /team/{id} from the victim's session returned 403 You do not have permission to access this team, and a self-reinvite attempt returned 403 Only team admins can perform this action. Tenant-level senior-administrator role provided no override.

Step 3, the attacker destroys the team

DELETE /team/<team id>
Authorization: Bearer <attacker token>

Response: 200 {"success": true}. The team was hard-deleted. A follow-up GET returned 404 Team not found. Documents that other members had uploaded into the team lost their team association.

Intra-tenant variant

The same primitive worked inside a single customer. Any user the team creator invited as team admin (for example a junior employee with a viewer-level account role) could kick the creator and delete the team. Lower team roles (editor, viewer) were correctly rejected on both endpoints. Team-admin against team-admin was treated as peers with no protection for the original creator.

The Impact

As any user with the team-admin role, intra-tenant or cross-tenant, originally malicious or later compromised, an attacker could:

  • Permanently lock the team creator out of their own team. A single API call returned {"success": true} and the victim was gone. The victim's tenant-level senior administrator role provided no protection and no rejoin path.
  • Permanently delete the entire team. The endpoint returned {"success": true} and the team was gone for every member. Documents lost their team association.
  • Do this from a completely different customer tenant. No same-domain enrollment, no SSO trust, no shared account. The only prerequisite was one legitimate invitation as team admin.

Realistic exploitation paths against enterprise customers: a phished contractor's session wipes out customer projects across every tenant where that contractor holds a team-admin role, or a junior employee being terminated destroys every team they admin before access revocation lands.

Remediation

  • Tag the team creator. Persist a creatorSub or an immutable owner-membership row at team creation. Reject removal of the creator unless the caller is the same user (voluntary leave) or a tenant-level senior administrator performing an explicit ownership transfer.
  • Enforce role hierarchy on POST /team/user/remove. Require caller.teamRole > target.teamRole. For admin-removing-admin, require either that the caller is the team creator or an explicit confirmation flow plus an audit-log entry.
  • Restrict DELETE /team/{id} to the team creator or to a tenant-level senior administrator of the team's home tenant. A cross-tenant guest admin must not be able to delete the team.
  • Give the tenant-level senior administrator an override on every team in their own tenant. Today they have none, even the original creator with that role cannot regain access after being kicked.
  • Soft-delete teams instead of hard-delete, with an audit log and a recovery window. Notify all team members and the tenant-level senior administrator whenever a member is removed or a team is deleted.