Summary
A stored Cross-Site Scripting (XSS) vulnerability exists in Mercator due to the use of unescaped Blade directives ({!! !!}) in display templates.
An authenticated user with the User role can inject arbitrary JavaScript payloads into fields such as "contact point" when creating or editing entities. The payload is then executed in the browser of any user who views the affected page, including administrators.
Details
Mercator uses Laravel Blade templates to render entity data. Several display templates use the {!! $variable !!} syntax, which renders raw HTML without escaping. While this is intentional for rich-text fields managed by the CKEditor editor, it is also applied to plain-text fields such as the contact point field, which have no legitimate need to contain HTML.
Because no server-side sanitization is performed on user input before storage, an attacker can submit a malicious payload through the standard web interface or directly via the API, bypassing the client-side CKEditor protection entirely.
Attack scenario (User → Admin escalation)
- An attacker with a low-privilege User account creates or edits an entity and injects
a JavaScript payload into the contact point field.
- An administrator navigates to the page displaying that entity.
- The payload executes in the administrator's browser.
- The attacker can exfiltrate the administrator's XSRF-TOKEN and use it to perform
state-changing requests on behalf of the administrator.
Note: session cookie theft is mitigated by the HttpOnly flag on themercator_session cookie, but CSRF token exfiltration remains a concrete impact.
Affected components
- All Blade display templates using
{!! !!} on user-supplied plain-text fields
- Confirmed affected field: contact point (
contact) on entity pages
- Other fields using
{!! !!} may also be affected (full audit in progress)
Remediation
The fix will be released by 2026-02-22 and includes two layers of defense:
-
Input sanitization via FormRequest : Integration of mews/purifier (HTMLPurifier) in a BaseFormRequest class. Plain-text fields will be processed with strip_tags(), rich-text fields with Purifier::clean() using a restricted allow-list configuration.
-
Blade template correction : Systematic replacement of {!! !!} with {{ }} for all fields that do not require HTML rendering.
Credits
This vulnerability was discovered and responsibly disclosed by Hadrien Chauder, penetration tester, who reported it directly to the maintainer before any public disclosure and provided a detailed proof of concept.
Summary
A stored Cross-Site Scripting (XSS) vulnerability exists in Mercator due to the use of unescaped Blade directives (
{!! !!}) in display templates.An authenticated user with the User role can inject arbitrary JavaScript payloads into fields such as "contact point" when creating or editing entities. The payload is then executed in the browser of any user who views the affected page, including administrators.
Details
Mercator uses Laravel Blade templates to render entity data. Several display templates use the
{!! $variable !!}syntax, which renders raw HTML without escaping. While this is intentional for rich-text fields managed by the CKEditor editor, it is also applied to plain-text fields such as the contact point field, which have no legitimate need to contain HTML.Because no server-side sanitization is performed on user input before storage, an attacker can submit a malicious payload through the standard web interface or directly via the API, bypassing the client-side CKEditor protection entirely.
Attack scenario (User → Admin escalation)
a JavaScript payload into the contact point field.
state-changing requests on behalf of the administrator.
Note: session cookie theft is mitigated by the
HttpOnlyflag on themercator_sessioncookie, but CSRF token exfiltration remains a concrete impact.Affected components
{!! !!}on user-supplied plain-text fieldscontact) on entity pages{!! !!}may also be affected (full audit in progress)Remediation
The fix will be released by 2026-02-22 and includes two layers of defense:
Input sanitization via FormRequest : Integration of
mews/purifier(HTMLPurifier) in aBaseFormRequestclass. Plain-text fields will be processed withstrip_tags(), rich-text fields withPurifier::clean()using a restricted allow-list configuration.Blade template correction : Systematic replacement of
{!! !!}with{{ }}for all fields that do not require HTML rendering.Credits
This vulnerability was discovered and responsibly disclosed by Hadrien Chauder, penetration tester, who reported it directly to the maintainer before any public disclosure and provided a detailed proof of concept.