{"id":"PYSEC-2026-1504","summary":"Label Studio allows Cross-Site Scripting (XSS) via GET request to `/projects/upload-example` endpoint","details":"## Description\nLabel Studio's `/projects/upload-example` endpoint allows injection of arbitrary HTML through a `GET` request with an appropriately crafted `label_config` query parameter. By crafting a specially formatted XML label config with inline task data containing malicious HTML/JavaScript, an attacker can achieve Cross-Site Scripting (XSS). While the application has a Content Security Policy (CSP), it is only set in report-only mode, making it ineffective at preventing script execution.\n\nThe vulnerability exists because the upload-example endpoint renders user-provided HTML content without proper sanitization on a GET request. This allows attackers to inject and execute arbitrary JavaScript in victims' browsers by getting them to visit a maliciously crafted URL.\n\nThis is considered vulnerable because it enables attackers to execute JavaScript in victims' contexts, potentially allowing theft of sensitive data, session hijacking, or other malicious actions.\n\n## Steps to reproduce\n1. Create a malicious label config that includes an XSS payload in embedded task data:\n\n```xml\n\u003cView\u003e\u003c!-- {\"data\": {\"text\": \"\u003cdiv\u003e\u003cimg src=x\nonerror=eval(atob(`YWxlcnQoIlhTUyIp`))\u003e\u003c/div\u003e\"}} --\u003e\u003cHyperText name=\"text\"\nvalue=\"$text\"/\u003e\u003c/View\u003e\n```\n\n\n2. URL encode the payload and access the following URL:\n\n- http://app/projects/upload-example/?label_config=%3CView%3E%3C!--%20{%22data%22:%20{%22text%22:%20%22%3Cdiv%3E%3Cimg%20src=x%20onerror=eval(atob(`YWxlcnQoIlhTUyIp`))%3E%3C/div%3E%22}}%20--%3E%3CHyperText%20name=%22text%22%20value=%22$text%22/%3E%3C/View%3E\n\nWhen executed, the payload causes the application to render an HTML page containing an img tag that fails to load, triggering the onerror event handler which executes base64-decoded JavaScript, demonstrating successful XSS execution in the victim's browser.\n   \n## Mitigations\n- Enable the Content Security Policy in enforcement mode instead of report-only mode to actively block unauthorized script execution\n- Deprecate the `GET` behavior at the `example-config` endpoint since it's not used \n\n## Impact\nThe vulnerability requires no special privileges and can be exploited by getting a victim to visit a crafted URL. The impact is high as it allows arbitrary JavaScript execution in victims' browsers, potentially exposing sensitive data or enabling account takeover through session theft.","aliases":["CVE-2025-25296","GHSA-wpq5-3366-mqw4"],"modified":"2026-07-07T17:47:16.440623946Z","published":"2026-07-07T14:34:49.691604Z","references":[{"type":"WEB","url":"https://github.com/HumanSignal/label-studio/security/advisories/GHSA-wpq5-3366-mqw4"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-25296"},{"type":"WEB","url":"https://github.com/HumanSignal/label-studio/commit/8cf6958e1e27ef6a03ed287e674470975d340885"},{"type":"PACKAGE","url":"https://github.com/HumanSignal/label-studio"},{"type":"PACKAGE","url":"https://pypi.org/project/label-studio"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-wpq5-3366-mqw4"}],"affected":[{"package":{"name":"label-studio","ecosystem":"PyPI","purl":"pkg:pypi/label-studio"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.16.0"}]}],"versions":["0.4.1","0.4.2","0.4.3","0.4.4","0.4.4.post1","0.4.4.post2","0.4.5","0.4.6","0.4.6.post1","0.4.6.post2","0.4.7","0.4.8","0.5.0","0.5.1","0.6.0","0.6.1","0.7.0","0.7.1","0.7.2","0.7.3","0.7.4","0.7.4.post0","0.7.4.post1","0.7.5.post1","0.7.5.post2","0.8.0","0.8.0.post0","0.8.1","0.8.1.post0","0.8.2","0.8.2.post0","0.9.0","0.9.0.post2","0.9.0.post3","0.9.0.post4","0.9.0.post5","0.9.1","0.9.1.post0","0.9.1.post1","0.9.1.post2","1.0.0","1.0.0.post0","1.0.0.post1","1.0.0.post2","1.0.0.post3","1.0.1","1.0.2","1.0.2.post0","1.1.0","1.1.0rc0","1.1.1","1.10.0","1.10.0.post0","1.10.1","1.11.0","1.12.0","1.12.0.post0","1.12.1","1.13.0","1.13.1","1.14.0","1.14.0.post0","1.15.0","1.2","1.3","1.3.post0","1.3.post1","1.4","1.4.1","1.4.1.post0","1.4.1.post1","1.5.0","1.5.0.post0","1.6.0","1.7.0","1.7.1","1.7.2","1.7.3","1.8.0","1.8.1","1.8.2","1.8.2.post0","1.8.2.post1","1.9.0","1.9.1","1.9.1.post0","1.9.2","1.9.2.post0"],"database_specific":{"source":"https://github.com/pypa/advisory-database/blob/main/vulns/label-studio/PYSEC-2026-1504.yaml"}}],"schema_version":"1.7.5","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"}]}