Technologies

Django

A Django site is recognisable from the hidden `csrfmiddlewaretoken` field in its forms and from its default cookie names, `csrftoken` and `sessionid`. Two defaults matter in an audit: the session and CSRF cookies are not marked `Secure` unless the settings say so, and the CSRF cookie is readable by JavaScript by default. Django's own documentation says never to deploy with `DEBUG` on, because debug mode displays detailed error pages.

How the engine recognises it

A `csrfmiddlewaretoken` field in the markup — weight 75, the strongest signal, since Django's template tag names it that way.

A `csrftoken` or `sessionid` cookie — weight 45, which only adds to the score: both names are common enough elsewhere that they do not prove Django alone.

A site with forms is recognised with high confidence; a site with no forms and only the cookies is reported at medium confidence at best.

Python itself is never inferred from these signals, and neither is the server in front.

Cookie defaults

`SESSION_COOKIE_SECURE` defaults to `False`, so the session cookie is sent over plain HTTP unless the setting is changed.

`CSRF_COOKIE_SECURE` also defaults to `False`, with the same consequence for the CSRF cookie.

`SESSION_COOKIE_HTTPONLY` defaults to `True`, so the session cookie is hidden from script.

`CSRF_COOKIE_HTTPONLY` defaults to `False`; the documentation notes that marking it HttpOnly offers no practical protection.

An audit reads the flags each cookie actually carries, which is what shows whether the Secure settings were changed.

DEBUG

`DEBUG` defaults to `False`, and the settings reference says never to deploy a site into production with it turned on.

One of debug mode's main features is the display of detailed error pages: a traceback with metadata about the environment, including the currently defined settings, minus those Django recognises as sensitive.

From outside it is visible only when an error occurs during the scan, and the absence of a debug page does not prove it is off.

Django's deployment checklist recommends running `manage.py check --deploy`, which reports this and other production settings from inside.

What recognition does and does not prove

It proves the forms or cookies were produced by Django's conventions.

It does not reveal the Django version, which none of the signals carries.

It does not identify the application server or the web server in front of it.

It says nothing about the admin interface, whose path is configurable and is not probed.

Which checks apply

`technology.inventory` lists the detection with its evidence.

`cookies.secure`, `cookies.httponly`, `cookies.samesite` and `cookies.inventory` report the flags actually set on the session and CSRF cookies.

`transport.hsts` reports whether browsers are told to stay on HTTPS, which Django sets only when configured to.

`api.errors.disclosure` reports detailed errors when an error response is met.

HTTPS and header settings

`SECURE_SSL_REDIRECT` defaults to `False`; when enabled, Django's security middleware redirects all non-HTTPS requests to HTTPS.

`SECURE_HSTS_SECONDS` defaults to `0`, so Django sends no Strict-Transport-Security header until a non-zero value is set.

`SECURE_CONTENT_TYPE_NOSNIFF` defaults to `True`, so the security middleware adds `X-Content-Type-Options: nosniff`.

`X_FRAME_OPTIONS` defaults to `'DENY'`, the value used by the clickjacking middleware.

A Django site behind a proxy may redirect and send HSTS from the proxy instead; the audit reports what the responses show.

`ALLOWED_HOSTS` defaults to an empty list and names the host names the site may serve, which the documentation describes as a protection against HTTP Host header attacks.

Frequently asked questions

Why is my Django session cookie not marked Secure?
Because `SESSION_COOKIE_SECURE` defaults to False. Set it to True on a site served over HTTPS, and do the same with `CSRF_COOKIE_SECURE`.
Should the CSRF cookie be HttpOnly?
Django's documentation says it offers no practical protection, and the default is False. The session cookie is the one that matters, and it is HttpOnly by default.
How do I check production settings properly?
Run `manage.py check --deploy`, as the deployment checklist recommends. An external scan sees effects; the command reads the settings.

Sources

Related

VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.

Scan a website