The checksecure
management command¶
The checksecure
management command is a “linter” for simple improvements
you could make to your site’s security configuration. It just runs a list of
check functions. Each check function can return a set of warnings, or the
empty set if it finds nothing to warn about.
When to run it¶
You can run it in your local development checkout. Your local dev settings
module may not be configured for SSL, so you may want to point it at a
different settings module, either by setting the DJANGO_SETTINGS_MODULE
environment variable, or by passing the --settings
option:
django-admin.py checksecure --settings=production_settings
Or you could run it directly on a production or staging deployment to verify that the correct settings are in use.
You could even make it part of your integration test suite, if you want. The
djangosecure.check.run_checks()
function runs all configured checks
and returns the complete set of warnings; you could write a simple test that
asserts that the returned value is empty.
Built-in checks¶
The following check functions are built-in to django-secure, and will run by default:
-
djangosecure.check.djangosecure.
check_security_middleware
()¶ Warns if SecurityMiddleware is not in your
MIDDLEWARE_CLASSES
.
-
djangosecure.check.djangosecure.
check_sts
()¶ Warns if SECURE_HSTS_SECONDS is not set to a non-zero value.
-
djangosecure.check.djangosecure.
check_sts_include_subdomains
()¶ Warns if SECURE_HSTS_INCLUDE_SUBDOMAINS is not
True
.
-
djangosecure.check.djangosecure.
check_frame_deny
()¶ Warns if SECURE_FRAME_DENY is not
True
.
-
djangosecure.check.djangosecure.
check_content_type_nosniff
()¶ Warns if SECURE_CONTENT_TYPE_NOSNIFF is not
True
.
-
djangosecure.check.djangosecure.
check_xss_filter
()¶ Warns if SECURE_BROWSER_XSS_FILTER is not
True
.
-
djangosecure.check.djangosecure.
check_ssl_redirect
()¶ Warns if SECURE_SSL_REDIRECT is not
True
.
-
djangosecure.check.djangosecure.
check_secret_key
()¶ Warns if SECRET_KEY is empty, missing, or has a very low number of different characters.
Warns if you appear to be using Django’s session framework and the SESSION_COOKIE_SECURE setting is not
True
. This setting marks Django’s session cookie as a secure cookie, which instructs browsers not to send it along with any insecure requests. Since it’s trivial for a packet sniffer (e.g. Firesheep) to hijack a user’s session if the session cookie is sent unencrypted, there’s really no good excuse not to have this on. (It will prevent you from using sessions on insecure requests; that’s a good thing).
Warns if you appear to be using Django’s session framework and the SESSION_COOKIE_HTTPONLY setting is not
True
. This setting marks Django’s session cookie as “HTTPOnly”, meaning (in supporting browsers) its value can’t be accessed from client-side scripts. Turning this on makes it less trivial for an attacker to escalate a cross-site scripting vulnerability into full hijacking of a user’s session. There’s not much excuse for leaving this off, either: if your code depends on reading session cookies from Javascript, you’re probably doing it wrong.
-
djangosecure.check.csrf.
check_csrf_middleware
()¶ Warns if you do not have Django’s built-in CSRF protection enabled globally via the CSRF view middleware. It’s important to CSRF protect any view that modifies server state; if you choose to do that piecemeal via the csrf_protect view decorator instead, just disable this check.
Suggestions for additional built-in checks (or better, patches implementing them) are welcome!
Modifying the list of check functions¶
By default, all of the built-in checks are run when
you run ./manage.py checksecure
. However, some of these checks may not be
appropriate for your particular deployment configuration. For instance, if you
do your HTTP->HTTPS redirection in a loadbalancer, it’d be irritating for
checksecure
to constantly warn you about not having enabled
SECURE_SSL_REDIRECT. You can customize the list of checks by setting the
SECURE_CHECKS setting; you can just copy the default value and remove a
check or two; you can also write your own custom checks.
Writing custom check functions¶
A checksecure
check function can be any Python function that takes no
arguments and returns a Python iterable of warnings (an empty iterable if it
finds nothing to warn about).
Optionally, the function can have a messages
attribute, which is a
dictionary mapping short warning codes returned by the function (which will be
displayed by checksecure
if run with --verbosity=0
) to longer
explanations which will be displayed by checksecure
when running at its
default verbosity level. For instance:
from django.conf import settings
def check_dont_let_the_bad_guys_in():
if settings.LET_THE_BAD_GUYS_IN:
return ["BAD_GUYS_LET_IN"]
return []
check_dont_let_the_bad_guys_in.messages = {
"BAD_GUYS_LET_IN": (
"Longer explanation of why it's a bad idea to let the bad guys in, "
"and how to correct the situation.")
}