Stored XSS in Django Admin Portal in django-treebeard/django-treebeard


Reported on

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. (1) a Django model subclasses AL_Node class from treebeard.al_tree
  2. (2) the Django model is registered to the admin panel using treebeard's TreeAdmin class
  3. (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 :

from django.db import models
from treebeard.al_tree import AL_Node

class Project(AL_Node):
    parent = models.ForeignKey('self',
    name = models.CharField(max_length=100)
    node_order_by = ['name', ]

    def __str__(self) -> str:

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, 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 , 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.


If successfully exploited , an attacker is able to inject arbitrary javascript code that gets stored in the database and executed when an administrator visit the list of entries of the affected model.

We are processing your report and will contact the django-treebeard team within 24 hours. a year ago
goodguyandy modified the report
a year ago
goodguyandy modified the report
a year ago
We created a GitHub Issue asking the maintainers to create a a year ago
We have contacted a member of the django-treebeard team and are waiting to hear back 10 months ago
We have sent a follow up to the django-treebeard team. We will try again in 7 days. 10 months ago
Samir Shah gave praise 10 months ago
The researcher's credibility has slightly increased as a result of the maintainer's thanks: +1
django-treebeard/django-treebeard maintainer has acknowledged this report 10 months ago
Samir Shah validated this vulnerability 10 months ago
goodguyandy has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
10 months ago


Hey @admin, thank you. It's possible to get a CVE assigned for this? thanks!

Samir Shah marked this as fixed in 4.6.1 with commit f0e197 10 months ago
The fix bounty has been dropped
This vulnerability will not receive a CVE
This vulnerability is scheduled to go public on Feb 12th 2023
10 months ago


@solarissmoke - hey Samir, thank you for your hard work and dedication to maintaining secure and reliable code.

As Djangotreebeard it's widely used library and I found this vuln in a real penetration test. Having a CVE can greatly assist other developers in identifying if they are affected by the issue.

Huntr , as a CNA, can assign the CVE in a matter of minutes.

If you prefer not to, don't worry. Anyway, thanks for your work.

Ben Harvie
10 months ago


CVE assignment is in the hands of the maintainer, they have the option to assign one during the publication process:)

Samir Shah published this vulnerability 10 months ago
to join this conversation