Mercator has a Personal Identifiable Information Leak from Query Executor feature
Description
Mercator is an open source web application that enables mapping of the information system. Prior to version 2025.05.19, Mercator's Query Engine (/admin/queries/execute) accepts a JSON DSL (from / select / filters / traverse / output), translates it into an Eloquent query, and returns results as JSON. The controller method QueryController::execute() does not enforce an authorization gate, unlike store() and massDestroy() in the same controller which are correctly protected. As a result, any authenticated account — including the read-only Auditor role — can query models beyond its intended scope, including the User model. Additionally, the password column, although declared $hidden, is not excluded from filter predicates, which allows it to be used in LIKE conditions. The schema() and schemaModel() endpoints of the same controller are similarly unguarded. The Query Engine is read-only; integrity and availability are not affected. Version 2025.05.19 patches the issue.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Affected products
1- Range: <2025.05.19
Patches
Vulnerability mechanics
Root cause
"Missing authorization gate in QueryController::execute() allows any authenticated user to query models beyond their intended scope."
Attack vector
An authenticated attacker with any role (including the read-only Auditor role) sends a crafted JSON DSL payload to the `/admin/queries/execute` endpoint. Because no authorization gate is enforced, the attacker can query models beyond their intended scope, including the `User` model. By using the `password` column in `LIKE` filter predicates and observing the `meta.count` in responses, the attacker can progressively reconstruct a bcrypt hash character by character [ref_id=1]. Exploitation requires a valid Mercator account and direct network access to the application (AT:N) [ref_id=1].
Affected code
The controller method `QueryController::execute()` (line 133) does not enforce an authorization gate, unlike `store()` and `massDestroy()` which correctly call `abort_if(Gate::denies(...))`. The `schema()` and `schemaModel()` endpoints are similarly unguarded. The `password` column, though declared `$hidden` on the `User` model, is not excluded from filter predicates, allowing it to be used in `LIKE` conditions.
What the fix does
The advisory states that version 2025.05.19 patches the issue [ref_id=1]. The patch is expected to add an authorization gate (e.g., `abort_if(Gate::denies(...))`) to `QueryController::execute()`, `schema()`, and `schemaModel()`, mirroring the protection already present in `store()` and `massDestroy()`. Additionally, the `password` column should be excluded from filter predicates to prevent its use in `LIKE` conditions.
Preconditions
- authAttacker must hold a valid Mercator account with at minimum the Configure permission
- networkDirect network access to the application is required
Generated on Jun 20, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
1- github.com/sourcentis/mercator/security/advisories/GHSA-q3r8-3h7c-96w3mitrex_refsource_CONFIRM
News mentions
0No linked articles in our index yet.