October 17, 2026
CVE-2026โ111437 Writeup
General Desctiption

By gearheader
3 min read
General Desctiption
During a recent security code audit of popular open-source Python packages, I identified a resource exhaustion vulnerability affecting django-import-export, a widely used data import/export extension for Django applications.
Assigned CVE-2026โ111437, this vulnerability allows an authenticated user with import permissions to trigger a severe Denial of Service (DoS) via CPU resource exhaustion by supplying a specially crafted numeric input string. In this write-up, we will examine the root cause, walk through the vulnerable code logic, and review the impact and remediation steps.
Vulnerability Overview
- CVE ID: CVE-2026โ111437
- Affected Component: IntegerWidget.clean() in import_export/widgets.py
- Affected Versions: >= v2.7.0 up to <= v4.4.2
- CWE Classification: CWE-405: Asymmetric Resource Consumption (Amplification) / CWE-400
- CVSS 3.1 Score: 6.5 (Medium) โ AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
Proof of Concept (PoC) & Attack Scenario
To reproduce or verify this behavior in a local testing environment:
- Set up the project
- Clone the repository
git clone https://github.com/django-import-export/django-import-export.git
cd django-import-export
- Create and activate an enviroment
python3 -m venv .venv
source .venv/bin/activate
- Then install the project
python -m pip install -e .
- Set the example project up inside /tests and create an admin account
cd tests
python manage.py check
python manage.py migrate
python manage.py createsuperuser
- Start the application
python manage.py runserver
By default it should be on http://127.0.0.1:8000
- Prepare a minimalist CSV file where an integer column contains a crafted scientific notation payload:
- Initiate an import via the Django admin panel or import utility.
Upon submitting and parsing the row, the server worker process locks up, pegging the CPU at 100% and halting response handling for other concurrent requests, effectively creating a targeted Denial of Service (DoS).
this can be done by Anyone(staff,admin) with import permissions
Impact & CVSS Assessment
Because this requires authenticated access with import permissions (PR:L), the vulnerability does not allow remote code execution, data theft, or database corruption (C:N, I:N). However, because a single malicious import file can exhaust worker threads and crash application servers under heavy concurrency, the Availability impact is rated as High (A:H), leading to an overall CVSS score of 6.5 (Medium).
Disclosure Timeline & Responsible Disclosures
Following Coordinated Vulnerability Disclosure (CVD) best practices, I attempted to reach out privately to the project maintainers via their designated security contact (djangoimportexport@gmail.com) with a full technical advisory and reproduction report.
After a considerable time they have reached me out and started to work on a fix.
Root Cause Analysis: Unbounded Decimal Conversion
The core issue lies within how django-import-export parses integer values during data imports. When processing spreadsheet or CSV columns mapped to integer fields, the library utilizes IntegerWidget to clean and sanitize input cell values before database operations.
Let's look at the vulnerable code pattern in import_export/widgets.py:
# Conceptual representation of vulnerable parsing logic
def clean(self, value, row=None, *args, **kwargs):
if value is None:
return None
# Vulnerable conversion path
return int(Decimal(sanitize_separators(value)))# Conceptual representation of vulnerable parsing logic
def clean(self, value, row=None, *args, **kwargs):
if value is None:
return None
# Vulnerable conversion path
return int(Decimal(sanitize_separators(value)))When Python converts a large decimal string with a massive exponent (such as 1e1000000) into a Python Decimal object and subsequently casts it to an int, Python must calculate the exact integer value representing that number. Because there are no length checks or exponent boundaries enforced prior to conversion, Python consumes 100% of a worker CPU core for an extended period trying to compute the digits.
Remediation & Fix Recommendations
To remediate this vulnerability, maintainers or developers patching downstream forks should implement strict validation checks on input lengths and decimal exponents before performing type coercion:
MAX_INPUT_LENGTH = 20
def clean(self, value, row=None, *args, **kwargs):
if value is None:
return None
val_str = str(value).strip()
if len(val_str) > MAX_INPUT_LENGTH:
raise ValueError("Numeric input exceeds allowed length constraints.")
return int(Decimal(sanitize_separators(val_str)))
MAX_INPUT_LENGTH = 20
def clean(self, value, row=None, *args, **kwargs):
if value is None:
return None
val_str = str(value).strip()
if len(val_str) > MAX_INPUT_LENGTH:
raise ValueError("Numeric input exceeds allowed length constraints.")
return int(Decimal(sanitize_separators(val_str)))Finder/Author: Ulvi Gulmaliyev