123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- ==================
- Security in Django
- ==================
- This document is an overview of Django's security features. It includes advice
- on securing a Django-powered site.
- .. _cross-site-scripting:
- Cross site scripting (XSS) protection
- =====================================
- .. highlightlang:: html+django
- XSS attacks allow a user to inject client side scripts into the browsers of
- other users. This is usually achieved by storing the malicious scripts in the
- database where it will be retrieved and displayed to other users, or by getting
- users to click a link which will cause the attacker's JavaScript to be executed
- by the user's browser. However, XSS attacks can originate from any untrusted
- source of data, such as cookies or Web services, whenever the data is not
- sufficiently sanitized before including in a page.
- Using Django templates protects you against the majority of XSS attacks.
- However, it is important to understand what protections it provides
- and its limitations.
- Django templates :ref:`escape specific characters <automatic-html-escaping>`
- which are particularly dangerous to HTML. While this protects users from most
- malicious input, it is not entirely foolproof. For example, it will not
- protect the following:
- .. code-block:: html+django
- <style class={{ var }}>...</style>
- If ``var`` is set to ``'class1 onmouseover=javascript:func()'``, this can result
- in unauthorized JavaScript execution, depending on how the browser renders
- imperfect HTML.
- It is also important to be particularly careful when using ``is_safe`` with
- custom template tags, the :ttag:`safe` template tag, :mod:`mark_safe
- <django.utils.safestring>`, and when autoescape is turned off.
- In addition, if you are using the template system to output something other
- than HTML, there may be entirely separate characters and words which require
- escaping.
- You should also be very careful when storing HTML in the database, especially
- when that HTML is retrieved and displayed.
- Cross site request forgery (CSRF) protection
- ============================================
- CSRF attacks allow a malicious user to execute actions using the credentials
- of another user without that user's knowledge or consent.
- Django has built-in protection against most types of CSRF attacks, providing you
- have :ref:`enabled and used it <using-csrf>` where appropriate. However, as with
- any mitigation technique, there are limitations. For example, it is possible to
- disable the CSRF module globally or for particular views. You should only do
- this if you know what you are doing. There are other :ref:`limitations
- <csrf-limitations>` if your site has subdomains that are outside of your
- control.
- :ref:`CSRF protection works <how-csrf-works>` by checking for a nonce in each
- POST request. This ensures that a malicious user cannot simply "replay" a form
- POST to your Web site and have another logged in user unwittingly submit that
- form. The malicious user would have to know the nonce, which is user specific
- (using a cookie).
- Be very careful with marking views with the ``csrf_exempt`` decorator unless
- it is absolutely necessary.
- SQL injection protection
- ========================
- SQL injection is a type of attack where a malicious user is able to execute
- arbitrary SQL code on a database. This can result in records
- being deleted or data leakage.
- By using Django's querysets, the resulting SQL will be properly escaped by
- the underlying database driver. However, Django also gives developers power to
- write :ref:`raw queries <executing-raw-queries>` or execute
- :ref:`custom sql <executing-custom-sql>`. These capabilities should be used
- sparingly and you should always be careful to properly escape any parameters
- that the user can control. In addition, you should exercise caution when using
- :meth:`extra() <django.db.models.query.QuerySet.extra>`.
- Clickjacking protection
- =======================
- Clickjacking is a type of attack where a malicious site wraps another site
- in a frame. This attack can result in an unsuspecting user being tricked
- into performing unintended actions on the target site.
- Django contains :ref:`clickjacking protection <clickjacking-prevention>` in
- the form of the
- :mod:`X-Frame-Options middleware <django.middleware.clickjacking.XFrameOptionsMiddleware>`
- which in a supporting browser can prevent a site from being rendered inside
- a frame. It is possible to disable the protection on a per view basis
- or to configure the exact header value sent.
- The middleware is strongly recommended for any site that does not need to have
- its pages wrapped in a frame by third party sites, or only needs to allow that
- for a small section of the site.
- SSL/HTTPS
- =========
- It is always better for security, though not always practical in all cases, to
- deploy your site behind HTTPS. Without this, it is possible for malicious
- network users to sniff authentication credentials or any other information
- transferred between client and server, and in some cases -- **active** network
- attackers -- to alter data that is sent in either direction.
- If you want the protection that HTTPS provides, and have enabled it on your
- server, there are some additional steps to consider to ensure that sensitive
- information is not leaked:
- * Set up redirection so that requests over HTTP are redirected to HTTPS.
- It is possible to do this with a piece of Django middleware. However, this has
- problems for the common case of a Django app running behind a reverse
- proxy. Often, reverse proxies are configured to set the ``X-Forwarded-SSL``
- header (or equivalent) if the incoming connection was HTTPS, and the absence
- of this header could be used to detect a request that was not HTTPS. However,
- this method usually cannot be relied on, as a client, or a malicious active
- network attacker, could also set this header.
- So, for the case of a reverse proxy, it is recommended that the main Web
- server should be configured to do the redirect to HTTPS, or configured to send
- HTTP requests to an app that unconditionally redirects to HTTPS.
- * Use 'secure' cookies.
- If a browser connects initially via HTTP, which is the default for most
- browsers, it is possible for existing cookies to be leaked. For this reason,
- you should set your :setting:`SESSION_COOKIE_SECURE` and
- :setting:`CSRF_COOKIE_SECURE` settings to ``True``. This instructs the browser
- to only send these cookies over HTTPS connections. Note that this will mean
- that sessions will not work over HTTP, and the CSRF protection will prevent
- any POST data being accepted over HTTP (which will be fine if you are
- redirecting all HTTP traffic to HTTPS).
- .. _additional-security-topics:
- Host headers and virtual hosting
- ================================
- Django uses the ``Host`` header provided by the client to construct URLs
- in certain cases. While these values are sanitized to prevent Cross
- Site Scripting attacks, they can be used for Cross-Site Request
- Forgery and cache poisoning attacks in some circumstances. We
- recommend you ensure your Web server is configured such that:
- * It always validates incoming HTTP ``Host`` headers against the expected
- host name.
- * Disallows requests with no ``Host`` header.
- * Is *not* configured with a catch-all virtual host that forwards requests
- to a Django application.
- Additionally, as of 1.3.1, Django requires you to explicitly enable support for
- the ``X-Forwarded-Host`` header if your configuration requires it.
- Additional security topics
- ==========================
- While Django provides good security protection out of the box, it is still
- important to properly deploy your application and take advantage of the
- security protection of the Web server, operating system and other components.
- * Make sure that your Python code is outside of the Web server's root. This
- will ensure that your Python code is not accidentally served as plain text
- (or accidentally executed).
- * Take care with any :ref:`user uploaded files <file-upload-security>`.
- * Django does not throttle requests to authenticate users. To protect against
- brute-force attacks against the authentication system, you may consider
- deploying a Django plugin or Web server module to throttle these requests.
- * If your site accepts file uploads, it is strongly advised that you limit
- these uploads in your Web server configuration to a reasonable
- size in order to prevent denial of service (DOS) attacks. In Apache, this
- can be easily set using the LimitRequestBody_ directive.
- * Keep your :setting:`SECRET_KEY` a secret.
- * It is a good idea to limit the accessibility of your caching system and
- database using a firewall.
- .. _LimitRequestBody: http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestbody
|