Django FileField validation and how we paid 550 CHF for that

by Dmytro Litvinov


Django warmed me everywhere in documentation like many times that we don't need to trust on users' upload of files and we paid for that 550 CHF for that 😐

That's how I would start my story about the XSS attack via uploading files in our Django project where we were opened for a bug-bounty program and white hackers found that issue πŸ˜…

Does it mean that my experience cost the company 550 CHF? Definitely, yes.
Does it mean that right now pay attention to that in new Django projects? Definitely yes ❗

The problem is pretty simple - a user created a new file called for example xss.jpeg and edited file and placed next content like <html><body><script>alert('I am BATMAN(crossed) XSS attack!')</script></body></html>
After that, we choose that file and on uploading we change content-type from image/jpeg to text/html via Burp Suite for example and voila! XSS via uploaded file is done.

Ahh.. and also I was not able to reproduce the issue initially as it was described since on my attempts I was banned by Cloudflare 😎 because of Managed Ruleset with rule XSS, HTML Injection - Script Tag.

Lesson learned: Validate the file type, don't trust the Content-Type header as it can be spoofed

For not learning the hard way, we also need to read File Upload Cheat Sheet πŸ‘

Where Django warned me multiple times 😲

The content-type header uploaded with the file (e.g. text/plain or application/pdf). Like any data supplied by the user, you shouldn’t trust that the uploaded file is actually this type. You’ll still need to validate that the file contains the content that the content-type header claims – β€œtrust but verify.”
There are security risks if you are accepting uploaded content from untrusted users! See the security guide’s topic on User-uploaded content for mitigation details.
Note that whenever you deal with uploaded files, you should pay close attention to where you’re uploading them and what type of files they are, to avoid security holes. Validate all uploaded files so that you’re sure the files are what you think they are. For example, if you blindly let somebody upload files, without validation, to a directory that’s within your web server’s document root, then somebody could upload a CGI or PHP script and execute that script by visiting its URL on your site. Don’t allow that.

Forewarned is forearmed 🀝

How I solved

In one of my digests which I did for the company where I work SoftFormance, I found a library called file-validator which I successfully integrated to eliminate the issue. 1 year ago I mentioned it but not used and today it cost us 550 CHF so I started to use it. I know the price of usage for that library))

The only problem is that pure-magic library does not work in my case for uploading .zip files,nevertheless, I just explicitly wrote libraries=['python_magic', 'mimetypes', 'filetype', 'django'] for DjangoFileValidator without pure_magic and it works πŸŽ‰