Browser can be tricked into executing uploaded malicious code

Your website is vulnerable to being tricked into executing uploaded malcious code because the SECURE_CONTENT_TYPE_NOSNIFF setting is not set.

SecurityMiddleware sets the X-Content-Type-Options header to nosniff when SECURE_CONTENT_TYPE_NOSNIFF = True to prevent hackers from tricking your website into executing a malicious javascript file that they uploaded via one of your forms.

This header indicates to the browser that the MIME types advertised in the Content-Type headers should not be changed (by "sniffing" the content).

The sniffing feature is the browser being helpful when a developer or server misconfiguration misidentified the Content-Type. If the browser respected an incorrect MIME type then a javascript, css, or image file would not work and the website would break. Very helpful feature. But it can be abused:

  • A bad actor uploads HTML containing javascript (maybe pretending to be an image file).
  • The file is served by your website but does not set MIME type in the Content-Type header
  • The browser infers the MIME type based on the content
  • The browser executes the javascript

By setting SECURE_CONTENT_TYPE_NOSNIFF = True, the browser will not infer the MIME type if the Content-Type is not set, closing this security hole.

So in practice, do this


MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    ...
]

SECURE_CONTENT_TYPE_NOSNIFF = True

Instead of this


MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    ...
]

Are you affected by this? Audit your codebase in seconds to find out.

Configuring this check

Django Doctor will run this check by default. No configuration is needed but the check can be turned on/off using check code missing-secure-content-type-nosniff in your pyproject.toml file.

Read more about configuring Django Doctor.