Skip to content

fix: escape release notes from external version server (#7960) - #7968

Open
wakqasahmed wants to merge 1 commit into
monicahq:4.xfrom
wakqasahmed:fix/issue-7960-supply-chain-xss
Open

fix: escape release notes from external version server (#7960)#7968
wakqasahmed wants to merge 1 commit into
monicahq:4.xfrom
wakqasahmed:fix/issue-7960-supply-chain-xss

Conversation

@wakqasahmed

Copy link
Copy Markdown

Fixes #7960

Vulnerability

app/Console/Commands/PingVersionServer.php:88 stores $json['notes'] — fetched from the external version.monicahq.com server by the scheduled monica:ping command — verbatim into Instance::latest_release_notes, with no sanitization.

resources/views/partials/check.blade.php:23 then rendered that field using Blade's unescaped output syntax: {!! $instance->latest_release_notes !!}. This partial is included from resources/views/partials/footer.blade.php, which loads on every authenticated page.

If an attacker can influence the response from version.monicahq.com (DNS hijack, BGP manipulation, or direct compromise of that server), arbitrary HTML/JavaScript gets stored in the database and executes in the browser of every authenticated user, on every self-hosted Monica instance with version checking enabled (the default), whenever they open the "What's new" modal. No individual Monica instance needs to be compromised.

Fix

Changed check.blade.php:23 from {!! $instance->latest_release_notes !!} to {{ $instance->latest_release_notes }}, per the issue's own recommended fix — a one-character change that makes Blade HTML-escape the content instead of rendering it raw. This is the precise vector cited in the issue; I did not change the ingestion/fetch code, since escaping at render time closes the vulnerability regardless of what the external server returns.

Tests

Added tests/Unit/Views/CheckVersionBladeTest.php::it_escapes_release_notes_fetched_from_the_version_server, which renders partials.check with an Instance whose latest_release_notes contains a <script> payload and asserts the rendered HTML contains the HTML-entity-escaped form, not a live <script> tag.

Disclosure: PHP is not available in the environment these changes were authored in, so this test could not be executed locally. It was written to match this repo's existing Pest/PHPUnit test conventions (see tests/Commands/Scheduling/PingVersionServerTest.php for the same Instance factory usage) and should be run in CI/a working dev environment before merge.

…cahq#7960)

The self-hosted "what's new" version-check modal rendered
Instance::latest_release_notes with Blade's unescaped {!! !!} syntax.
That field is populated verbatim from the JSON response of an external
server (version.monicahq.com) by the monica:ping scheduled command.
A compromised or DNS-hijacked version server could inject arbitrary
HTML/JS that executes in every authenticated user's session across all
self-hosted instances with version checking enabled. Switched to
Blade's escaped {{ }} syntax so the notes are always rendered as text.
@CLAassistant

CLAassistant commented Aug 18, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants