Broken Access Control continues to be one of the most impactful vulnerabilities in modern applications — and when combined with IDOR, the results can be severe.

In this write-up, I'll walk through how I discovered a vulnerability that allowed an attacker to delete participants from conversations belonging to other Personal accounts — without authorization.

— -

## 🔎 Summary

A critical **Broken Access Control** vulnerability combined with an **Insecure Direct Object Reference (IDOR)** allowed an attacker to:

- Delete participants from conversations they do not own - Modify other users' conversations - Escalate privileges horizontally

The root cause? The backend trusted client-supplied identifiers without verifying ownership or authorization.

— -

## 🧠 What Went Wrong?

Two key issues made this attack possible:

### 1️⃣ Participant Management Endpoint Lacked Authorization Checks

The backend trusted:

- `conversationId` - `participantsUuids`

There was **no server-side validation** to confirm that:

- The authenticated user owned the conversation - The user had permission to modify that conversation - The participant UUIDs belonged to a conversation they were authorized to manage

In short: the server assumed the client was honest.

— -

### 2️⃣ IDOR in Contacts Endpoint

Another issue existed in:

GET /api/contacts/{email}

This endpoint allowed retrieving **any user's UUID** simply by knowing their email address.

This meant an attacker could:

- Enumerate user UUIDs - Collect identifiers needed to manipulate conversations

On its own, this is an IDOR. Combined with the participant management flaw — it becomes much more powerful.

— -

## ⚙️ Attack Scenario (Personal Accounts)

### 🛠 Environment Setup

Three accounts were created:

- Attacker #1 (Personal) - Attacker #2 (Personal) - Victim (Personal)

— -

### Step 1 — Obtain the Victim's Conversation ID

From the Victim account:

- Invite Attacker #1 into a conversation.

From Attacker #1:

- Intercept a conversation-related request. - Extract the `conversationId`.

Now the attacker has:

✔ Valid victim `conversationId`

— -

### Step 2 — Retrieve Victim UUID via IDOR

From an attacker account:

GET /api/contacts/victim@email.com => Vulnerable with IDOR via email

The response exposes the victim's data including his UUID.

Now the attacker has:

✔ Victim `participantsUuids`

— -

### Step 3 — Exploit Participant Management

From Attacker #2:

1. Open one of their own conversations. 2. Use **Manage Participants**. 3. Remove any participant. 4. Intercept the request. 5. Send it to Repeater. 6. Modify the body: — Replace attacker `conversationId` with victim `conversationId` — Replace `participantsUuids` with victim UUID(s) 7. Send the modified request.

— -

## 💥 Result

The server responds:

And the victim's participant is successfully deleted from their conversation.

  • No authorization.
  • No ownership validation.
  • No permission checks.