CVE-2023-31047 Overview
CVE-2023-31047 is an input validation vulnerability affecting Django web framework versions 3.2 before 3.2.19, 4.x before 4.1.9, and 4.2 before 4.2.1. The vulnerability enables attackers to bypass file validation when using a single form field to upload multiple files. While forms.FileField and forms.ImageField never officially supported multiple file uploads (only validating the last uploaded file), Django's documentation on "Uploading multiple files" incorrectly suggested this functionality was supported, creating a security gap that could be exploited.
Critical Impact
Attackers can bypass file type and content validation by uploading multiple files through a single form field, potentially uploading malicious files such as web shells or malware while only the last file is validated.
Affected Products
- Django 3.2 before 3.2.19
- Django 4.x before 4.1.9
- Django 4.2 before 4.2.1 (including beta and release candidate versions)
- Fedora 38 (bundled Django packages)
Discovery Timeline
- 2023-05-03 - Django Project releases security patches
- 2023-05-07 - CVE-2023-31047 published to NVD
- 2025-01-29 - Last updated in NVD database
Technical Details for CVE-2023-31047
Vulnerability Analysis
This vulnerability stems from a fundamental design limitation in Django's file upload handling combined with misleading documentation. When a form field is configured to accept multiple file uploads using the HTML5 multiple attribute, Django's forms.FileField and forms.ImageField classes only process and validate the last file in the upload sequence. This creates a dangerous scenario where an attacker can submit multiple files, with malicious content in the earlier files and a benign file last, effectively bypassing all file validation checks.
The vulnerability is classified under CWE-20 (Improper Input Validation) and CWE-862 (Missing Authorization), reflecting both the input handling deficiency and the lack of proper access controls on file uploads.
Root Cause
The root cause lies in the architectural design of Django's file form fields. The forms.FileField and forms.ImageField classes were never designed to handle multiple file uploads, yet the framework's documentation provided examples suggesting this functionality was supported. When multiple files are submitted to a single field, the validation logic only examines the final file in the upload request, leaving all preceding files unvalidated. This disconnect between documented behavior and actual implementation creates an exploitable validation gap.
Attack Vector
The attack is network-based and requires no authentication or user interaction. An attacker can craft a malicious HTTP POST request containing multiple files in a single form field. By placing a malicious file (such as a PHP web shell, executable, or specially crafted image containing embedded code) before a benign file that passes validation, the attacker can bypass Django's file validation entirely.
The exploitation mechanism involves:
- Identifying a Django application with a file upload form using FileField or ImageField
- Crafting a multipart form request with multiple files in the same field
- Placing malicious content in all files except the last one
- Submitting the request where only the final benign file is validated
- The malicious files may be saved to the server without validation
Detection Methods for CVE-2023-31047
Indicators of Compromise
- Unexpected file types present in upload directories that don't match allowed extensions
- Multiple files uploaded in short succession from the same source with only one matching validation rules
- Web shells or executable files in directories intended for images or documents
- Anomalous HTTP POST requests with unusually large multipart form data containing multiple file attachments
Detection Strategies
- Monitor web server logs for multipart form requests with multiple Content-Disposition: form-data; filename= entries for the same field name
- Implement file integrity monitoring on upload directories to detect unexpected file types
- Deploy web application firewalls (WAF) with rules to inspect multipart form submissions for multiple file uploads to single fields
- Review Django application logs for file upload events and correlate with actual files stored on disk
Monitoring Recommendations
- Enable verbose logging for file upload handlers in Django applications
- Configure alerts for file uploads that don't match expected MIME types in upload directories
- Implement periodic scanning of upload directories for known malicious file signatures
- Monitor for unusual file access patterns or execution attempts in upload directories
How to Mitigate CVE-2023-31047
Immediate Actions Required
- Upgrade Django to version 3.2.19, 4.1.9, or 4.2.1 or later immediately
- Review all file upload implementations in your Django applications for potential exploitation
- Scan upload directories for suspicious files that may have been uploaded before patching
- Implement additional server-side file validation independent of Django's form validation
Patch Information
Django Project has released security patches addressing this vulnerability. The fixes are available in Django versions 3.2.19, 4.1.9, and 4.2.1. Organizations should upgrade to these versions or later as soon as possible. For detailed patch information, refer to the Django Security Release Notes and the Django Weblog Security Release announcement.
Fedora users should apply the updated Django packages as announced through the Fedora Package Announcements.
Workarounds
- Remove the multiple attribute from file input fields if multiple file uploads are not explicitly required
- Implement custom form field validation that iterates through all uploaded files rather than only the last
- Add server-side validation logic outside of Django's form handling to validate all files in the request
- Use allowlist-based file type checking at the web server level in addition to Django validation
- Consider implementing a separate file scanning service that validates all uploaded content before storage
# Upgrade Django to patched version
pip install --upgrade Django>=3.2.19
# Verify installed version
python -c "import django; print(django.get_version())"
# For production environments, update requirements.txt
echo "Django>=4.2.1" >> requirements.txt
pip install -r requirements.txt
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

