123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455 |
- ==========================
- Django's security policies
- ==========================
- Django's development team is strongly committed to responsible
- reporting and disclosure of security-related issues. As such, we've
- adopted and follow a set of policies which conform to that ideal and
- are geared toward allowing us to deliver timely security updates to
- the official distribution of Django, as well as to third-party
- distributions.
- .. _reporting-security-issues:
- Reporting security issues
- =========================
- **Short version: please report security issues by emailing
- security@djangoproject.com**.
- Most normal bugs in Django are reported to `our public Trac instance`_, but
- due to the sensitive nature of security issues, we ask that they **not** be
- publicly reported in this fashion.
- Instead, if you believe you've found something in Django which has security
- implications, please send a description of the issue via email to
- ``security@djangoproject.com``. Mail sent to that address reaches the `security
- team <https://www.djangoproject.com/foundation/teams/#security-team>`_.
- Once you've submitted an issue via email, you should receive an acknowledgment
- from a member of the security team within 3 working days. After that, the
- security team will begin their analysis. Depending on the action to be taken,
- you may receive followup emails. It can take several weeks before the security
- team comes to a conclusion. There is no need to chase the security team unless
- you discover new, relevant information. All reports aim to be resolved within
- the industry-standard 90 days. Confirmed vulnerabilities with a
- :ref:`high severity level <severity-levels>` will be addressed promptly.
- .. admonition:: Sending encrypted reports
- If you want to send an encrypted email (*optional*), the public key ID for
- ``security@djangoproject.com`` is ``0xfcb84b8d1d17f80b``, and this public
- key is available from most commonly-used keyservers.
- .. _our public Trac instance: https://code.djangoproject.com/query
- Reporting guidelines
- --------------------
- Include a runnable proof of concept
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Please privately share a minimal Django project or code snippet that
- demonstrates the potential vulnerability. Include clear instructions on how to
- set up, run, and reproduce the issue.
- Please do not attach screenshots of code.
- User input must be sanitized
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Reports based on a failure to sanitize user input are not valid security
- vulnerabilities. It is the developer's responsibility to properly handle user
- input. This principle is explained in our :ref:`security documentation
- <sanitize-user-input>`.
- For example, the following is **not considered valid** because ``email`` has
- not been sanitized::
- from django.core.mail import send_mail
- from django.http import JsonResponse
- def my_proof_of_concept(request):
- email = request.GET.get("email", "")
- send_mail("Email subject", "Email body", email, ["admin@example.com"])
- return JsonResponse(status=200)
- Developers must **always validate and sanitize input** before using it. The
- correct approach would be to use a Django form to ensure ``email`` is properly
- validated::
- from django import forms
- from django.core.mail import send_mail
- from django.http import JsonResponse
- class EmailForm(forms.Form):
- email = forms.EmailField()
- def my_proof_of_concept(request):
- form = EmailForm(request.GET)
- if form.is_valid():
- send_mail(
- "Email subject",
- "Email body",
- form.cleaned_data["email"],
- ["admin@example.com"],
- )
- return JsonResponse(status=200)
- return JsonResponse(form.errors, status=400)
- Similarly, as Django's raw SQL constructs (such as :meth:`~.QuerySet.extra` and
- :class:`.RawSQL` expression) provide developers with full control over the
- query, they are insecure if user input is not properly handled. As explained in
- our :ref:`security documentation <sql-injection-protection>`, it is the
- developer's responsibility to safely process user input for these functions.
- For instance, the following is **not considered valid** because ``query`` has
- not been sanitized::
- from django.shortcuts import HttpResponse
- from .models import MyModel
- def my_proof_of_concept(request):
- query = request.GET.get("query", "")
- q = MyModel.objects.extra(select={"id": query})
- return HttpResponse(q.values())
- Request headers and URLs must be under 8K bytes
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- To prevent denial-of-service (DoS) attacks, production-grade servers impose
- limits on request header and URL sizes. For example, by default Gunicorn allows
- up to roughly:
- * `4k bytes for a URL`_
- * `8K bytes for a request header`_
- Other web servers, such as Nginx and Apache, have similar restrictions to
- prevent excessive resource consumption.
- Consequently, the Django security team will not consider reports that rely on
- request headers or URLs exceeding 8K bytes, as such inputs are already
- mitigated at the server level in production environments.
- .. admonition:: :djadmin:`runserver` should never be used in production
- Django's built-in development server does not enforce these limits because
- it is not designed to be a production server.
- .. _`4k bytes for a URL`: https://docs.gunicorn.org/en/stable/settings.html#limit-request-line
- .. _`8k bytes for a request header`: https://docs.gunicorn.org/en/stable/settings.html#limit-request-field-size
- The request body must be under 2.5 MB
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The :setting:`DATA_UPLOAD_MAX_MEMORY_SIZE` setting limits the default maximum
- request body size to 2.5 MB.
- As this is enforced on all production-grade Django projects by default, a proof
- of concept must not exceed 2.5 MB in the request body to be considered valid.
- Issues resulting from large, but potentially reasonable setting values, should
- be reported using the `public ticket tracker`_ for hardening.
- .. _public ticket tracker: https://code.djangoproject.com/
- Code under test must feasibly exist in a Django project
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The proof of concept must plausibly occur in a production-grade Django
- application, reflecting real-world scenarios and following standard development
- practices.
- Django contains many private and undocumented functions that are not part of
- its public API. If a vulnerability depends on directly calling these internal
- functions in an unsafe way, it will not be considered a valid security issue.
- Content displayed by the Django Template Language must be under 100 KB
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The Django Template Language (DTL) is designed for building the content needed
- to display web pages. In particular its text filters are meant for that kind of
- usage.
- For reference, the complete works of Shakespeare have about 3.5 million bytes
- in plain-text ASCII encoding. Displaying such in a single request is beyond the
- scope of almost all websites, and so outside the scope of the DTL too.
- Text processing is expensive. Django makes no guarantee that DTL text filters
- are never subject to degraded performance if passed deliberately crafted,
- sufficiently large inputs. Under default configurations, Django makes it
- difficult for sites to accidentally accept such payloads from untrusted
- sources, but, if it is necessary to display large amounts of user-provided
- content, it’s important that basic security measures are taken.
- User-provided content should always be constrained to known maximum length. It
- should be filtered to remove malicious content, and validated to match expected
- formats. It should then be processed offline, if necessary, before being
- displayed.
- Proof of concepts which use over 100 KB of data to be processed by the DTL will
- be considered invalid.
- .. _security-report-evaluation:
- How does Django evaluate a report
- =================================
- These are criteria used by the security team when evaluating whether a report
- requires a security release:
- * The vulnerability is within a :ref:`supported version <security-support>` of
- Django.
- * The vulnerability does not depend on manual actions that rely on code
- external to Django. This includes actions performed by a project's developer
- or maintainer using developer tools or the Django CLI. For example, attacks
- that require running management commands with uncommon or insecure options
- do not qualify.
- * The vulnerability applies to a production-grade Django application. This
- means the following scenarios do not require a security release:
- * Exploits that only affect local development, for example when using
- :djadmin:`runserver`.
- * Exploits which fail to follow security best practices, such as failure to
- sanitize user input. For other examples, see our :ref:`security
- documentation <cross-site-scripting>`.
- * Exploits in AI generated code that do not adhere to security best practices.
- The security team may conclude that the source of the vulnerability is within
- the Python standard library, in which case the reporter will be asked to report
- the vulnerability to the Python core team. For further details see the `Python
- security guidelines <https://www.python.org/dev/security/>`_.
- On occasion, a security release may be issued to help resolve a security
- vulnerability within a popular third-party package. These reports should come
- from the package maintainers.
- If you are unsure whether your finding meets these criteria, please still report
- it :ref:`privately by emailing security@djangoproject.com
- <reporting-security-issues>`. The security team will review your report and
- recommend the correct course of action.
- .. _security-support:
- Supported versions
- ==================
- At any given time, the Django team provides official security support
- for several versions of Django:
- * The `main development branch`_, hosted on GitHub, which will become the
- next major release of Django, receives security support. Security issues that
- only affect the main development branch and not any stable released versions
- are fixed in public without going through the :ref:`disclosure process
- <security-disclosure>`.
- * The two most recent Django release series receive security
- support. For example, during the development cycle leading to the
- release of Django 1.5, support will be provided for Django 1.4 and
- Django 1.3. Upon the release of Django 1.5, Django 1.3's security
- support will end.
- * :term:`Long-term support release`\s will receive security updates for a
- specified period.
- When new releases are issued for security reasons, the accompanying
- notice will include a list of affected versions. This list is
- comprised solely of *supported* versions of Django: older versions may
- also be affected, but we do not investigate to determine that, and
- will not issue patches or new releases for those versions.
- .. _main development branch: https://github.com/django/django/
- .. _severity-levels:
- Security issue severity levels
- ==============================
- The severity level of a security vulnerability is determined by the attack
- type.
- Severity levels are:
- * **High**
- * Remote code execution
- * SQL injection
- * **Moderate**
- * Cross site scripting (XSS)
- * Cross site request forgery (CSRF)
- * Denial-of-service attacks
- * Broken authentication
- * **Low**
- * Sensitive data exposure
- * Broken session management
- * Unvalidated redirects/forwards
- * Issues requiring an uncommon configuration option
- .. _security-disclosure:
- How Django discloses security issues
- ====================================
- Our process for taking a security issue from private discussion to
- public disclosure involves multiple steps.
- Approximately one week before public disclosure, we send two notifications:
- First, we notify |django-announce| of the date and approximate time of the
- upcoming security release, as well as the severity of the issues. This is to
- aid organizations that need to ensure they have staff available to handle
- triaging our announcement and upgrade Django as needed.
- Second, we notify a list of :ref:`people and organizations
- <security-notifications>`, primarily composed of operating-system vendors and
- other distributors of Django. This email is signed with the PGP key of someone
- from `Django's release team`_ and consists of:
- * A full description of the issue and the affected versions of Django.
- * The steps we will be taking to remedy the issue.
- * The patch(es), if any, that will be applied to Django.
- * The date on which the Django team will apply these patches, issue
- new releases and publicly disclose the issue.
- On the day of disclosure, we will take the following steps:
- #. Apply the relevant patch(es) to Django's codebase.
- #. Issue the relevant release(s), by placing new packages on the :pypi:`Python
- Package Index <Django>` and on the `djangoproject.com website
- <https://www.djangoproject.com/download/>`_, and tagging the new release(s)
- in Django's git repository.
- #. Post a public entry on `the official Django development blog`_,
- describing the issue and its resolution in detail, pointing to the
- relevant patches and new releases, and crediting the reporter of
- the issue (if the reporter wishes to be publicly identified).
- #. Post a notice to the |django-announce| and oss-security@lists.openwall.com
- mailing lists that links to the blog post.
- .. _the official Django development blog: https://www.djangoproject.com/weblog/
- If a reported issue is believed to be particularly time-sensitive --
- due to a known exploit in the wild, for example -- the time between
- advance notification and public disclosure may be shortened
- considerably.
- Additionally, if we have reason to believe that an issue reported to
- us affects other frameworks or tools in the Python/web ecosystem, we
- may privately contact and discuss those issues with the appropriate
- maintainers, and coordinate our own disclosure and resolution with
- theirs.
- The Django team also maintains an :doc:`archive of security issues
- disclosed in Django</releases/security>`.
- .. _Django's release team: https://www.djangoproject.com/foundation/teams/#releasers-team
- .. _security-notifications:
- Who receives advance notification
- =================================
- The full list of people and organizations who receive advance
- notification of security issues is not and will not be made public.
- We also aim to keep this list as small as effectively possible, in
- order to better manage the flow of confidential information prior to
- disclosure. As such, our notification list is *not* simply a list of
- users of Django, and being a user of Django is not sufficient reason
- to be placed on the notification list.
- In broad terms, recipients of security notifications fall into three
- groups:
- 1. Operating-system vendors and other distributors of Django who
- provide a suitably-generic (i.e., *not* an individual's personal
- email address) contact address for reporting issues with their
- Django package, or for general security reporting. In either case,
- such addresses **must not** forward to public mailing lists or bug
- trackers. Addresses which forward to the private email of an
- individual maintainer or security-response contact are acceptable,
- although private security trackers or security-response groups are
- strongly preferred.
- 2. On a case-by-case basis, individual package maintainers who have
- demonstrated a commitment to responding to and responsibly acting
- on these notifications.
- 3. On a case-by-case basis, other entities who, in the judgment of the
- Django development team, need to be made aware of a pending
- security issue. Typically, membership in this group will consist of
- some of the largest and/or most likely to be severely impacted
- known users or distributors of Django, and will require a
- demonstrated ability to responsibly receive, keep confidential and
- act on these notifications.
- .. admonition:: Security audit and scanning entities
- As a policy, we do not add these types of entities to the notification
- list.
- Requesting notifications
- ========================
- If you believe that you, or an organization you are authorized to
- represent, fall into one of the groups listed above, you can ask to be
- added to Django's notification list by emailing
- ``security@djangoproject.com``. Please use the subject line "Security
- notification request".
- Your request **must** include the following information:
- * Your full, real name and the name of the organization you represent,
- if applicable, as well as your role within that organization.
- * A detailed explanation of how you or your organization fit at least
- one set of criteria listed above.
- * A detailed explanation of why you are requesting security notifications.
- Again, please keep in mind that this is *not* simply a list for users of
- Django, and the overwhelming majority of users should subscribe to
- |django-announce| to receive advanced notice of when a security release will
- happen, without the details of the issues, rather than request detailed
- notifications.
- * The email address you would like to have added to our notification
- list.
- * An explanation of who will be receiving/reviewing mail sent to that
- address, as well as information regarding any automated actions that
- will be taken (i.e., filing of a confidential issue in a bug
- tracker).
- * For individuals, the ID of a public key associated with your address
- which can be used to verify email received from you and encrypt
- email sent to you, as needed.
- Once submitted, your request will be considered by the Django
- development team; you will receive a reply notifying you of the result
- of your request within 30 days.
- Please also bear in mind that for any individual or organization,
- receiving security notifications is a privilege granted at the sole
- discretion of the Django development team, and that this privilege can
- be revoked at any time, with or without explanation.
- .. admonition:: Provide all required information
- A failure to provide the required information in your initial contact
- will count against you when making the decision on whether or not to
- approve your request.
|