diff options
Diffstat (limited to 'docs/topics/security.txt')
| -rw-r--r-- | docs/topics/security.txt | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/docs/topics/security.txt b/docs/topics/security.txt new file mode 100644 index 0000000000..f411bcf7b1 --- /dev/null +++ b/docs/topics/security.txt @@ -0,0 +1,168 @@ +==================== + Security in Django +==================== + +This document will show you the security features of Django as well +as give some advice about securing a Django 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 acheived by storing the malicious +scripts to the database where it will be retrieved and displayed to other users +or to get users to click a link containing variables containing scripts that +will be rendered by the user's browser. However, XSS attacks can originate +from any untrusted source of data such as cookies or web services. + +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 +malications 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 to the database especially +when that HTML will be 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 website 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 +of 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 data POST data being accepted over HTTP (which will be fine if you are + redirecting all HTTP traffic to HTTPS). + +.. _additional-security-topics: + +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. +* 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 + the 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 + |
