Security guide

Anything related to users or user accounts has security implications and represents a large source of potential security issues. This document is not an exhaustive guide to those implications and issues, and makes no guarantees that your particular use of Django or django-registration will be safe; instead, it provides a set of recommendations, and explanations for why django-registration does certain things or recommends particular approaches. Using this software responsibly is, ultimately, up to you.

Before continuing with this document, you should ensure that you’ve read and understood Django’s security documentation. Django provides a good overview of common security issues in the general field of web development, and an explanation of how it helps to protect against them or provides tools to help you do so.

You should also ensure you’re following Django’s security recommendations. You can check for many common issues by running:

python check --tag security

on your codebase.

Recommendation: use the HMAC workflow

Three user-signup workflows are included in django-registration, along with support for writing your own. If you choose to use one of the included workflows, the HMAC workflow is the recommended default.

The HMAC workflow provides a verification step – the user must click a link sent to the email address they used to register – which can serve as an impediment to automated account creation for malicious purposes. And unlike the model-based workflow, the HMAC workflow does not need to store any additional server-side data (other than the user account itself – the model workflow uses an additional model to store the activation key).

The HMAC workflow generates an activation key which consists of the new account’s username and the timestamp of the signup, verified using Django’s cryptographic signing tools which in turn use the HMAC implementation from the Python standard library. Thus, django-registration is not inventing or buliding any new cryptography, but only using existing/vetted implementations in an approved and standard manner.

Additionally, the HMAC workflow takes steps to ensure that its use of HMAC does not act as an oracle – several parts of Django use the signing tools, and third-party applications are free to use them as well, so django-registration makes use of the ability to supply a salt value for the purpose of “namespacing” HMAC usage. Thus an activation token generated by django-registration’s HMAC workflow should not be usable for attacks against other HMAC-carrying values generated by the same installation of Django.

Restrictions on user names: reserved names

By default, django-registration applies a list of reserved names, and does not permit users to create accounts using those names (see ReservedNameValidator). The default list of reserved names includes many names that could cause confusion or even inappropriate access. These reserved names fall into several categories:

  • Usernames which could allow a user to impersonate or be seen as a site administrator. For example, ‘admin’ or ‘administrator’.
  • Usernames corresponding to standard/protocol-specific email addresses (relevant for sites where creating an account also creates an email address with that username). For example, ‘webmaster’.
  • Usernames corresponding to standard/sensitive subdomain names (relevant for sites where creating an account also creates a subdomain corresponding to the username). For example, ‘ftp’ or ‘autodiscover’.
  • Usernames which correspond to sensitive URLs (relevant for sites where user profiles appear at a URL containing the username). For example, ‘contact’ or ‘buy’.

It is strongly recommended that you leave the reserved-name validation enabled.

Restrictions on user names and email addresses: Unicode

By default, django-registration permits the use of Unicode in usernames and email addresses. However, to prevent some types of Unicode-related attacks, django-registration will not permit certain specific uses of Unicode characters.

For example, while the username ‘admin’ cannot normally be registered (see above), a user might still attempt to register a name that appears visually identical, by substituting a Cyrillic ‘a’ or other similar-appearing character for the first character.

To prevent this, django-registration applies the following rule to usernames, and to the local-part and the domain of email addresses:

  • If the submitted value is mixed-script (contains characters from multiple different scripts, as in the above example which would mix Cyrillic and Latin characters), and
  • If the submitted value contains characters appearing in the Unicode Visually Confusable Characters file,
  • Then the value will be rejected.

This should not interfere with legitimate use of Unicode, or of non-English/non-Latin characters in usernames and email addresses. To avoid a common false-positive situation, the local-part and domain of an email address are checked independently of each other.

It is strongly recommended that you leave this validation enabled.