July 15, 2026
Organization Without Owner
بِسْمِ اللَّهِ الرَّحْمَنِ الرَّحِيــــــمِ
By Zyadabdelftah
3 min read
بِسْمِ اللَّهِ الرَّحْمَنِ الرَّحِيــــــمِ
Many people think bug bounty is just trying random things until… BOOM … a vulnerability shows up, you submit a report, and get paid. That's not how it works.
## Introduction
This isn't something you can just pick up and try on any random target. A blind attempt, with no research and no understanding of how the system actually works, will get you nowhere — you don't get to spray requests and expect a vulnerability to pop out on its own. That only happens in dreams.
So before anything else, here's the method I actually followed to land on a bug that leaves an organization without an owner — and effectively paralyzes it.
— —
Step one …?
The first thing I always do is understand how the organization works.
- Is it a Single Account organization model or a Multi Account model?
- If it's Multi Account, are memberships isolated between organizations, or could memberships overlap?
- If it's Single Account, is it possible for a user to somehow join another organization while already belonging to one?
Only after I understood how the organization model was supposed to behave — from the docs and from just using the product — did I start testing anything.
— — —
Step 2 — A Simple Idea
After understanding the model, one idea immediately came to my mind.
Suppose we have the following user.
_- User: _A@gmail.com
_- Current Organization: _MR2x_Org1
What would happen if I invited the exact same user into MR2x_Org2?
It looked like a simple test, but it could reveal how memberships were actually managed.
## A Simple Experiment
So I went to MR2x_Org2 and sent an invitation to A@gmail.com — the same email that was already a member of MR2x_Org1.
— -
## The HTTP 400 Response
The application blocked it immediately:
```http
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "This email already has an account in another organization."
}```http
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "This email already has an account in another organization."
}
Fair enough — that confirmed membership really is meant to be single: one account, one organization. But it also raised the question that led to everything else:
> _*"How is this validation actually implemented on the backend?"*_
#### **## Step 4 — Race Condition**
I decided to test the validation itself.
Instead of sending a single invitation request, I sent two requests at almost the exact same moment.
> _- Request #1 → Brand new email_
> _- Request #2 → A@gmail.com_
Both requests reached the server simultaneously.
This time, the invitation for ****A@gmail.com**** was created successfully.
— -
#### **## Step 5 — Unexpected Behavior**
User ****A**** accepted the invitation.
Immediately after accepting it:
> _- The user disappeared from __****MR2x_Org1****_
> _- The user joined __****MR2x_Org2****_
Something became very clear.
> Accepting an invitation doesn't create another membership.
It ****moves**** the user.
— -
#### **## Step 6 — One More Question**
At this point I had a working bug: I could move a _*member*_ between organizations, without their real consent, just by racing an acceptance against a second request. That's already a real issue. But one thought kept forming after that:
> _> __****"If this works for a regular member… what about the Owner?"****_
Every organization has exactly one Owner, and Owners aren't "just another member" — they hold all the administrative control. If the same technique worked on an Owner account, the impact would be a lot bigger than one misplaced member.
— -
#### **## Ownerless Organization**
So I tried the exact same method — again — but this time the invitation target was the ****Owner**** of MR2x_Org1 instead of a regular member.
The surprise: it worked. The Owner accepted the invitation into MR2x_Org2, and just like Member A, he was silently removed from MR2x_Org1.
****BEFORE****
> _- Organization → Owner → Members → Administrative Control_
****AFTER****
> _- Organization → Members → __****NO OWNER****__ → Governance Broken_
> ****Critical observation:**** MR2x_Org1 was left with members, but no Owner and no administrative role at all — nobody to manage settings, approve actions, or remove members. The organization was effectively orphaned.
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*DHTOgOotv-qoDhvcGvttuA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*DHTOgOotv-qoDhvcGvttuA.png 1x">
<img src="/img/medium/700/1*DHTOgOotv-qoDhvcGvttuA.png" alt="None" width="1254" height="1254" loading="lazy" data-zoom-src="/img/medium/4000/1*DHTOgOotv-qoDhvcGvttuA.png" class="prose-image"/>
</picture>
— -
#### **## Impact**
Once the Owner disappeared, the organization became effectively locked.
- Nobody could delete the organization.
- Nobody could change user roles.
- Nobody could remove members.
- Nobody could manage billing.
- Nobody could recover ownership.
The organization still existed.
But nobody actually owned it anymore.
— -
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*-bOKapgW0-rZ4kjg-PU11w.jpeg 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*-bOKapgW0-rZ4kjg-PU11w.jpeg 1x">
<img src="/img/medium/700/1*-bOKapgW0-rZ4kjg-PU11w.jpeg" alt="None" width="792" height="489" loading="lazy" data-zoom-src="/img/medium/4000/1*-bOKapgW0-rZ4kjg-PU11w.jpeg" class="prose-image"/>
</picture>
> Chick My [linkedin Account](https://www.linkedin.com/in/zyad-abdelftah/)
قال رسول الله صلى الله عليه وسلم
```typescript
من كانت الدُّنيا همَّه ، فرَّق اللهُ عليه أمرَه ،
وجعل فقرَه بين عينَيْه ،
ولم يأْتِه من الدُّنيا إلَّا ما كُتِب له
، ومن كانت الآخرةُ نيَّتَه ، جمع اللهُ له أمرَه ،
وجعل غناه في قلبِه ،
وأتته الدُّنيا وهي راغمةٌ
Fair enough — that confirmed membership really is meant to be single: one account, one organization. But it also raised the question that led to everything else:
> _*"How is this validation actually implemented on the backend?"*_
#### **## Step 4 — Race Condition**
I decided to test the validation itself.
Instead of sending a single invitation request, I sent two requests at almost the exact same moment.
> _- Request #1 → Brand new email_
> _- Request #2 → A@gmail.com_
Both requests reached the server simultaneously.
This time, the invitation for ****A@gmail.com**** was created successfully.
— -
#### **## Step 5 — Unexpected Behavior**
User ****A**** accepted the invitation.
Immediately after accepting it:
> _- The user disappeared from __****MR2x_Org1****_
> _- The user joined __****MR2x_Org2****_
Something became very clear.
> Accepting an invitation doesn't create another membership.
It ****moves**** the user.
— -
#### **## Step 6 — One More Question**
At this point I had a working bug: I could move a _*member*_ between organizations, without their real consent, just by racing an acceptance against a second request. That's already a real issue. But one thought kept forming after that:
> _> __****"If this works for a regular member… what about the Owner?"****_
Every organization has exactly one Owner, and Owners aren't "just another member" — they hold all the administrative control. If the same technique worked on an Owner account, the impact would be a lot bigger than one misplaced member.
— -
#### **## Ownerless Organization**
So I tried the exact same method — again — but this time the invitation target was the ****Owner**** of MR2x_Org1 instead of a regular member.
The surprise: it worked. The Owner accepted the invitation into MR2x_Org2, and just like Member A, he was silently removed from MR2x_Org1.
****BEFORE****
> _- Organization → Owner → Members → Administrative Control_
****AFTER****
> _- Organization → Members → __****NO OWNER****__ → Governance Broken_
> ****Critical observation:**** MR2x_Org1 was left with members, but no Owner and no administrative role at all — nobody to manage settings, approve actions, or remove members. The organization was effectively orphaned.
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*DHTOgOotv-qoDhvcGvttuA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*DHTOgOotv-qoDhvcGvttuA.png 1x">
<img src="/img/medium/700/1*DHTOgOotv-qoDhvcGvttuA.png" alt="None" width="1254" height="1254" loading="lazy" data-zoom-src="/img/medium/4000/1*DHTOgOotv-qoDhvcGvttuA.png" class="prose-image"/>
</picture>
— -
#### **## Impact**
Once the Owner disappeared, the organization became effectively locked.
- Nobody could delete the organization.
- Nobody could change user roles.
- Nobody could remove members.
- Nobody could manage billing.
- Nobody could recover ownership.
The organization still existed.
But nobody actually owned it anymore.
— -
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*-bOKapgW0-rZ4kjg-PU11w.jpeg 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*-bOKapgW0-rZ4kjg-PU11w.jpeg 1x">
<img src="/img/medium/700/1*-bOKapgW0-rZ4kjg-PU11w.jpeg" alt="None" width="792" height="489" loading="lazy" data-zoom-src="/img/medium/4000/1*-bOKapgW0-rZ4kjg-PU11w.jpeg" class="prose-image"/>
</picture>
> Chick My [linkedin Account](https://www.linkedin.com/in/zyad-abdelftah/)
قال رسول الله صلى الله عليه وسلم
```typescript
من كانت الدُّنيا همَّه ، فرَّق اللهُ عليه أمرَه ،
وجعل فقرَه بين عينَيْه ،
ولم يأْتِه من الدُّنيا إلَّا ما كُتِب له
، ومن كانت الآخرةُ نيَّتَه ، جمع اللهُ له أمرَه ،
وجعل غناه في قلبِه ،
وأتته الدُّنيا وهي راغمةٌ