Supply-Chain XSS via Unescaped External Version Server Response in Monica CRM
⚠️ This issue respects the following points: ⚠️
- This is a bug, not a question or a configuration/webserver/proxy issue.
- This issue is not already reported on Github (I've searched it).
- I agree to follow Monica's Code of Conduct.
Bug description
Monica CRM (v4.1.2, latest stable release) fetches release notes from an external server (version.monicahq.com) via a background cron job and stores the notes field directly in the database without sanitization. This content is rendered on every authenticated page load using Blade's unescaped output syntax ({!! !!}) in resources/views/partials/check.blade.php:23. If an attacker can influence the response from version.monicahq.com — through DNS hijacking, BGP route manipulation, or direct server compromise — arbitrary JavaScript executes in the browser of every authenticated Monica user across all self-hosted instances with version checking enabled (default: ON). This vulnerability has been present in every release since v0.6.0 (August 2017) — over 7 years unpatched. Real world precedent: the polyfill.io supply-chain attack (June 2024) used the identical vector, silently affecting ~380,000 websites without compromising any individual site.
Steps to reproduce
Observe the version check feature — Log in as admin. The dashboard shows a "New version available" badge. Clicking it opens a modal rendering release notes fetched from version.monicahq.com and stored in the database.
Identify the vulnerable code path — PingVersionServer.php:88 stores $json['notes'] raw into the database. check.blade.php:23 renders it via {!! $instance->latest_release_notes !!} — unescaped output.
Simulate a compromised version server — Inject a malicious payload into the database replicating what a DNS-hijacked version.monicahq.com would return: a
Source: monicahq/monica