MEx Backend
Broken Access Control on DELETE Endpoint
The DELETE /v0/merged-item/{identifier} endpoint is accessible with read-only credentials due to missing authorization on the router. A single DELETE request cascades, deleting the merged item, all linked extracted items, all rule-sets, and all nested objects with no recovery mechanism.
Description
The merged_router is registered with a read-access guard at main.py:80, but the router contains a DELETE endpoint that performs a destructive write operation. No endpoint-level authorization override restricts this to write-privileged users.
mex/backend/main.py:80
router.include_router(merged_router, dependencies=[Depends(has_read_access)])The DELETE endpoint at merged/main.py:64 inherits the read-only guard with no override:
mex/backend/merged/main.py:64-67
@router.delete( "/merged-item/{identifier}", status_code=status.HTTP_204_NO_CONTENT, tags=["editor"])def delete_merged_item( identifier: Annotated[Identifier, Path()], include_rule_set: Annotated[bool, Query(...)] = False,) -> None:The has_read_access guard verifies only that credentials exist in the read or write database. It does not check for write-level authorization or differentiate by HTTP method:
mex/backend/security.py:105
if api_key: api_key_database = settings.backend_api_key_database can_read = APIKey(api_key) in api_key_database.readDeletion cascades: a single DELETE request removes the merged item, all linked extracted items (from multiple ETL pipelines), all rule-sets, and all nested objects (Text, Link). There is no soft-delete or undo mechanism. Recovery requires re-ingestion from all source ETL pipelines.
By contrast, write operations on the ingest_router at main.py:77 correctly use Depends(has_write_access) and return 403 for read-only keys.
The same vulnerability exists in the testing application at testing/main.py:48.
The DELETE endpoint was introduced in v1.2.0 (2025-10-23). The merged_router has been registered with has_read_access since the router was created.
The MEx Editor currently uses a shared write-level API key for all backend requests regardless of user role, masking this vulnerability in practice. However, the editor codebase contains a TODO (MX-1616) for switching to per-user backend credentials. Once that migration is implemented, the backend's missing authorization on DELETE will become directly exploitable through the editor for any authenticated user.
Impact
- Any user with read-only credentials can delete arbitrary metadata items via the
DELETE /v0/merged-item/{identifier}endpoint. - In the MEx context, a researcher with read-only access can delete all items in the metadata catalog. Recovery requires re-ingestion from all source ETL pipelines.
Mitigation
Update to MEx Backend 1.8.0 or later. For older versions, add dependencies=[Depends(has_write_access)] to the @router.delete decorator at merged/main.py:64, or split the merged_router so GET endpoints keep has_read_access and the DELETE endpoint gets has_write_access. Apply the same fix at testing/main.py:48.
References
How We Can Help
Who We Are
The security researchers behind this advisory.

Dr. rer. nat. Simon Weber
Senior Pentester & MedSec Researcher
I evaluate your SaMD with the same industry-defining security insight I contributed to the BAK MV for the revision of the B3S standard.
- PhD on Hospital Cybersecurity
- Critical vulnerabilities found in hospital systems
- Alumni of THB MedSec Research Group
- gematik Security Hero

Dipl.-Inf. Volker Schönefeld
Senior Application Security Expert
As a former CTO and developer turned pentester, I work alongside your team to uncover vulnerabilities and find solutions that fit your architecture.
- 20+ years as CTO, 50M+ app downloads
- Architected and secured large-scale IoT fleets
- Certified Web Exploitation Specialist
- gematik Security Hero
Looking for a Penetration Test?
Machine Spirits specializes in security assessments for medical devices and healthcare IT. From MDR penetration testing to C5 cloud compliance, we help MedTech companies meet regulatory requirements.
