mirror of
https://github.com/django/django.git
synced 2025-03-12 10:22:37 +00:00
[5.2.x] Added security reporting guidelines.
Backport of 59353360590202fab04067e23214a825157c524b from main.
This commit is contained in:
parent
a39d0ff88f
commit
865337ae92
@ -43,6 +43,131 @@ the industry-standard 90 days. Confirmed vulnerabilities with a
|
||||
|
||||
.. _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.
|
||||
|
||||
.. _security-report-evaluation:
|
||||
|
||||
How does Django evaluate a report
|
||||
|
@ -5,6 +5,16 @@ Security in Django
|
||||
This document is an overview of Django's security features. It includes advice
|
||||
on securing a Django-powered site.
|
||||
|
||||
.. _sanitize-user-input:
|
||||
|
||||
Always sanitize user input
|
||||
==========================
|
||||
|
||||
The golden rule of web application security is to never trust user-controlled
|
||||
data. Hence, all user input should be sanitized before being used in your
|
||||
application. See the :doc:`forms documentation </topics/forms/index>` for
|
||||
details on validating user inputs in Django.
|
||||
|
||||
.. _cross-site-scripting:
|
||||
|
||||
Cross site scripting (XSS) protection
|
||||
|
Loading…
x
Reference in New Issue
Block a user