CVE-2026-42197
Stored XSS in RELATE's user profile allows for admin account takeover.
- CVSS 8.7
- CWE-79
- Input Validation and Sanitization
- Remote
RELATE is a web-based courseware package. Versions prior to commit 555f0efb1c5bd7531c07cd73724d7e566a81f620 have a stored cross-site scripting vulnerability that allows any enrolled student to execute arbitrary JavaScript in an administrator's browser session, potentially leading to full admin account takeover. The `get_user()` method in `ParticipationAdmin` renders user-controlled input using `mark_safe` combined with Python's % string formatting. This bypasses Django\'s automatic HTML escaping entirely. The value returned by `get_full_name` is derived directly from the `first_name` and `last_name` fields of the User model. These fields are freely editable by any authenticated user through the profile page (`/profile/`) with no sanitization applied. When an admin views the Participation list in the Django admin panel, the unsanitized value is rendered directly into the HTML response, causing the injected script to execute in the admin's browser. Commit 555f0efb1c5bd7531c07cd73724d7e566a81f620 fixes the issue.
- CWE
- CWE-79
- CVSS base score
- 8.7
- Published
- 2026-05-27
- OWASP
- A03 Injection
- Orthogonal defect classification
- Checking
- Code defect classification
- Missing Check
- Category
- Input Validation and Sanitization
- Subcategory
- Cross-Site Scripting (XSS)
- Accessibility scope
- Remote
- Impact
- Privilege Escalation
- Affected component
- RELATE
Solution
Update RELATE to a version that includes commit `555f0efb1c5bd7531c07cd73724d7e566a81f620` or newer.
Vulnerable code sample
# In a file like 'course/admin.py' within a Django project
from django.contrib import admin
from django.utils.safestring import mark_safe
from course.models import Participation
@admin.register(Participation)
class ParticipationAdmin(admin.ModelAdmin):
list_display = ("id", "get_user", "role")
# The user-controlled 'first_name' and 'last_name' fields are used
# to generate get_full_name(). The result is then formatted into
# a string that is marked as "safe" for rendering. This allows
# any HTML/JavaScript in the user's name to be rendered directly
# on the admin page, causing a stored XSS vulnerability.
def get_user(self, obj):
return mark_safe('<a href GIVEMEANAME="%d/">%s</a>' % (
obj.user.pk, obj.user.get_full_name()))
get_user.short_description = 'User'
get_user.admin_order_field = 'user'Patched code sample
from django.contrib import admin
from django.urls import reverse
from django.utils.html import format_html
class ParticipationAdmin(admin.ModelAdmin):
list_display = ("id", "get_user", "course", "time_stamp")
list_display_links = ("id",)
list_filter = ("course",)
search_fields = (
"user__first_name", "user__last_name", "user__username", "user__email")
readonly_fields = ("user", "course", "time_stamp")
def get_user(self, participation):
return format_html(
'<a href="{}">{}</a>',
reverse("admin:auth_user_change", args=(participation.user.pk,)),
participation.user.get_full_name())
get_user.short_description = 'User'
get_user.admin_order_field = 'user'Payload
<script>alert('XSS')</script>
Cite this entry
@misc{vaitp:cve202642197,
title = {{Stored XSS in RELATE's user profile allows for admin account takeover.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-42197},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-42197/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
