Stored XSS in Django Admin Portal in django-treebeard/django-treebeard
Sep 29th 2022
Django-treebeard suffers from a stored XSS in the TreeAdmin class when certain preconditions are met. The XSS it's triggered when a privileged user visit a page in the django admin portal. In order to successfully exploit this vulnerable, three pre-conditions should occur:
- (1) a Django model subclasses
- (2) the Django model is registered to the admin panel using treebeard's TreeAdmin class
- (3) The attacker should be able to write data in a model field that returns in the
__str__method of the model.
In order to better understand the prerequisites, please follow the proof of concept below.
Proof of Concept
In order to re-create a vulnerable scenario, first create a model , called for example Project, that subclass
AL_Node and returns a model's field in the
__str__ method of the model :
# models.py from django.db import models from treebeard.al_tree import AL_Node class Project(AL_Node): parent = models.ForeignKey('self', on_delete=models.CASCADE, related_name='children_set', verbose_name=('Father'), blank=True, null=True, db_index=True) name = models.CharField(max_length=100) node_order_by = ['name', ] def __str__(self) -> str: return self.name
Then, register the model "Project" to the Django admin site using treebeard's TreeAdmin:
from django.contrib import admin from core.models import Project from treebeard.admin import TreeAdmin admin.site.register(Project, TreeAdmin)
Now let's suppose an attacker is able to create a project with an arbitrary name, for example:
<script>alert(1)</script> to it.
Now, when an administrator visit the model list page in the Django admin site, the payload gets executed thus causing a stored XSS.
This stored appens due to improper sanitization appening on https://github.com/django-treebeard/django-treebeard/blob/70fd011f5a3bc7fe21653cbdba2c7d6e931aaec2/treebeard/templatetags/admin_tree_list.py#L27 , the str(node) parameter is in fact marked as safe when, in my opinion, it shouldn't as there is a chance it will contains user input.