Severity by source
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Network-accessible web UI, no attacker auth required to plant metadata via file import, scope changes to victim browser, with low C/I impact limited to session context.
Primary rating from Vendor (https://github.com/beetbox/beets).
CVSS VectorVendor: https://github.com/beetbox/beets
Lifecycle Timeline
5DescriptionCVE.org
During code logic analyis, an area that may lead to unintended behavior under specific conditions was discovered.
Overview
- Verified Version:
80cd21554124da07d17a4f962c7d770a4f70d0f2 - Vulnerability Type: Stored XSS
- Affected Location:
beetsplug/web/templates/index.html:42 - Trigger Scenario: Metadata fields such as
title,lyrics, orcommentsare rendered with raw template interpolation and inserted into DOM via.html(...).
Root Cause
The bundled web UI uses Underscore template interpolation mode <%= ... %> for untrusted metadata fields. In this runtime, <%= ... %> is raw insertion and HTML escaping is only performed by <%- ... %>. Rendered output is then inserted with .html(...), allowing attacker-controlled markup to become active DOM.
Source-to-Sink Chain
- Source (attacker-controlled input)
- Item metadata values (for example
title,lyrics,comments) can contain attacker HTML payload.
- Data flow
- Templates in
beetsplug/web/templates/index.html:42-46,87-91render metadata with<%= ... %>. - Underscore runtime defines
<%= ... %>as raw interpolation (beetsplug/web/static/underscore.js:890-907).
- Sink (security-sensitive action)
- Frontend inserts rendered template output into DOM via
$(this.el).html(this.template(this.model.toJSON()));inbeetsplug/web/static/beets.js:182,208,220.
Exploitation Preconditions
- Victim opens the web UI page that renders attacker-controlled metadata.
- Metadata includes executable HTML/JS payload.
Risk
Stored payload executes in the web UI context and can perform actions available to that origin.
Impact
Attacker can run arbitrary JavaScript in the victim browser, exfiltrate viewable data, and perform UI-driven actions as the victim session.
Remediation
- Replace raw interpolation
<%= ... %>with escaped output<%- ... %>for untrusted fields. - Avoid
.html(...)for untrusted template output; use text-safe rendering. - Sanitize metadata values on ingest and before rendering, including attribute contexts.
AnalysisAI
Stored XSS in the beets music library web UI (versions prior to 2.10.0) allows arbitrary JavaScript execution in a victim's browser when metadata fields such as title, lyrics, or comments contain attacker-controlled HTML payloads. The flaw stems from Underscore.js raw template interpolation (<%= ... %>) feeding untrusted metadata directly into jQuery's .html() DOM insertion method in beetsplug/web/static/beets.js. No active exploitation is confirmed - SSVC rates exploitation as none and EPSS sits at 0.05% (14th percentile) - but the attack is persistent once metadata is poisoned and does not require repeated attacker access.
Technical ContextAI
beets (pkg:pip/beets) is a Python-based music collection management tool that includes an optional web UI plugin (beetsplug/web). The web interface renders music item data using Backbone.js models and Underscore.js templates. CWE-79 (Improper Neutralization of Input During Web Page Generation) is the root cause class: Underscore defines two interpolation modes - <%= ... %> for raw, unescaped output and <%- ... %> for HTML-escaped output - and the templates at beetsplug/web/templates/index.html:42-46,87-91 use the unsafe raw form for user-controlled metadata fields. The rendered string is then passed to jQuery's .html() at beetsplug/web/static/beets.js:182,208,220, which parses and activates any embedded HTML/script content. The vulnerable commit is 80cd21554124da07d17a4f962c7d770a4f70d0f2; all releases packaging beets < 2.10.0 are affected per EUVD-2026-27055 and GHSA-3gxm-wfjx-m847.
RemediationAI
Vendor-released patch: beets 2.10.0. Upgrade via pip install --upgrade beets and verify with beet version; the release notes at https://github.com/beetbox/beets/releases/tag/v2.10.0 confirm this release. The fix replaces raw Underscore interpolation (<%= ... %>) with HTML-escaped syntax (<%- ... %>) for untrusted metadata fields and eliminates the unsafe .html() DOM insertion path. Debian LTS users can follow the announcement at https://lists.debian.org/debian-lts-announce/2026/06/msg00030.html for distribution-packaged backports. If immediate upgrade is blocked, the most effective compensating control is disabling the web UI plugin entirely by removing web from the plugins list in your beets configuration file - this eliminates the attack surface with no impact to CLI music-management workflows. Do not expose the beets web UI to untrusted networks as an interim measure; binding it to localhost or placing it behind authenticated reverse proxy reduces but does not eliminate risk if shared metadata is writable by untrusted parties.
Same weakness CWE-79 – Cross-site Scripting (XSS)
View allVendor StatusVendor
SUSE
Severity: MediumShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-27055
GHSA-3gxm-wfjx-m847