10 tips for making the Django Admin more secure

10 tips for making the Django Admin more secure

Don't take chances with app security. Here's how to protect your users.

Locks
Image by : 
x

Get the newsletter

Join the 85,000 open source advocates who receive our giveaway alerts and article roundups.

Offloading the responsibility for making your app secure onto QA testers or an information security office is tempting, but security is everyone's responsibility. The Django Admin is one of our favorite features of Django, but unless it's locked down correctly, it presents opportunities for exploitation. To save your users from compromised data, here are 10 tips to make the Django Admin more secure.

1. Use SSL

Deploy your site behind HTTPS. If you aren’t using HTTPS, it’s possible for someone to snoop your (or your users') password while you are at a coffee shop, an airport, or in another public place. Read more about enabling SSL and extra steps you might need to take in the Django docs).

2. Change the URL

Change the default admin URL from /admin/ to something else. Instructions are in the Django documentation, but in short, replace admin/ in your URL conf to something else:

urlpatterns = [
    path('my-special-admin-login/', admin.site.urls),
]

For even more security, host the admin on a different domain entirely. If you need even more security, serve the admin behind a VPN or someplace that isn't public.

3. Use 'django-admin-honeypot'

Once you have moved your admin site to a new URL (or even decided to host it on its own domain), install the library django-admin-honeypot on your old /admin/ URL to capture attempts to hack your site. django-admin-honeypot generates a fake admin login screen and will email your site administrators whenever someone tries to log in to your old /admin/ URL.

The email generated by django-admin-honeypot will contain the attacker's IP address, so for added security if you notice repeated login attempts from the same IP address, you can block that address from using your site.

4. Require stronger passwords

Most of your users will choose poor passwords. Enabling password validation can ensure that your users select stronger passwords, which will in turn increase the security of their data and the data they have access to in the admin. Require strong passwords by enabling password validation. The Django documentation has a great introduction on how to enable the password validators that ship with Django. Check out third-party password validators like django-zxcvbn-password to make your users' passwords even more secure. Scot Hacker has a great post on what makes a strong password and implementing the python-zxcvbn library in a Python project.

5. Use two-factor authentication

Two-factor authentication (2FA) is when you require a password plus something else to authenticate a user for your site. You are probably familiar with apps that require a password and then text you a second login code before they allow you to log in; those apps are using 2FA.

There are three ways you can enable 2FA on your site:

  • 2FA with SMS, where you text a login code. This is better than requiring only a password, but SMS messages are surprisingly easy to intercept.
  • 2FA with an app like Google Authenticator, which generates unique login codes for any service you register to it. To set up these apps, users will need to scan a QR code on your site to register your site with their app. Then the app will generate the login code that they can use to log in to your site.
  • 2FA with YubiKey is the safest way to enable 2FA on your site. This method requires that your users have a physical device, a YubiKey, that they plug into a USB port when they try to log in.

The library django-two-factor-auth can help you enable any of the above 2FA methods.

6. Use the latest version of Django

Always use the latest Django minor version to keep up with security updates and bugfixes. As of this writing, that is Django 2.0.1. Upgrade to the newest long-term release (LTS) as soon as is feasible for you, but definitely make sure your project is upgraded before it falls out of support (see supported versions on the Download) page.

7. Never run `DEBUG` in production

When DEBUG is set to True in your settings file, errors will display with full tracebacks that are likely to contain information you don't want end users to see. You might also have other settings or methods that are only enabled when in Debug mode that could pose a risk to your users and their data.

To avoid this, use different settings files for local development and for production deployment. Check out Vitor Freitas's great introduction to using multiple settings files.

8. Remember your environment

The admin should explicitly state which environment you are in to keep users from accidentally deleting production data. You can accomplish this easily using the django-admin-env-notice library, which will place a color-coded banner at the top of your Admin site.

9. Check for errors

This isn't specific to the Django Admin, but it's still a great practice to secure your app. Find security errors using python manage.py check --deploy. If you run this command when you're running your project locally, you will likely see some warnings that won't be relevant in production. For example, your DEBUG setting is probably True, but you're already using a separate settings file to take care of that for production, right?

The output for this command will look something like this:

?: (security.W002) You do not have 'django.middleware.clickjacking.XFrameOptionsMiddleware' in your MIDDLEWARE, so your pages will not be served with an 'x-frame-options' header. Unless there is a good reason for your site to be served in a frame, you should consider enabling this header to help prevent clickjacking attacks.
?: (security.W012) SESSION_COOKIE_SECURE is not set to True. Using a secure-only session cookie makes it more difficult for network traffic sniffers to hijack user sessions.
?: (security.W016) You have 'django.middleware.csrf.CsrfViewMiddleware' in your MIDDLEWARE, but you have not set CSRF_COOKIE_SECURE to True. Using a secure-only CSRF cookie makes it more difficult for network traffic sniffers to steal the CSRF token.

System check identified 3 issues (0 silenced).

Notice that each warning contains an explanation of what your risk is and what you should change. More information about this check is in the Django documentation.

10. Get a checkup

This is another tip that isn't specific to the admin, but is still good practice. Once deployed to a staging site, run your website through Sasha's Pony Checkup. This site will give you a security score and a tidy list of things to do to improve that score. It will test your site for some of the things we've listed above, and also recommend other ways to protect your site from specific vulnerabilities and types of attacks.

Further reading

Want more info on security in Django?

About the author

Jeff Triplett - Jeff Triplett is an open source developer with over 18 years of experience in the web and programming industries. He has held executive roles and technical positions at small startups and major corporations, including Leggett and Platt, ATC Transportation, and REVSYS. He occasionally blogs on his website. Jeff joined REVSYS as an engineer in 2011. Before that, Jeff worked on Ellington CMS...

About the author

Lacey Williams Henschel - Lacey Williams Henschel is a software engineer with REVSYS and part of the organizing team for DjangoCon US. In the past, she's chaired DjangoCon US, organized several Django Girls workshops, taught courses for Treehouse, and written about accessibility at tech events.