Unwanted HTTP methods
To deflect unwanted HTTP methods including the TRACE
method, configuring settings.py
, adding and configuring a file called middleware.py
will ensure unwated methods do not execute against your site.
Below are examples of this with some explanation.
Middleware + settings.py
Configure middleware in settings.py
:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'your_project.middleware.BlockUnsupportedMethodsMiddleware', # Add here (before CSRF)
'django.middleware.csrf.CsrfViewMiddleware', # CSRF comes after
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Middleware file
Additionally add the middlware.py that lives in the same directory as settings.py
from django.http import HttpResponseNotAllowed
class BlockUnsupportedMethodsMiddleware:
"""
Middleware to block unsupported HTTP methods globally.
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# Allowed methods for your site
allowed_methods = ['GET', 'POST']
if request.method not in allowed_methods:
return HttpResponseNotAllowed(allowed_methods)
return self.get_response(request)
The code above essentially will return 405
errors for TRACE
, PUT
, DELETE
, OPTIONS
, and any other HTTP methods.
This only allows GET
and POST
methods.
With having CSRF configured, POST
will return a 403
error and will state: Forbidden (CSRF cookie not set.)
.
What's the deal with Post?
Django is now configured in a way that ensures any POST
reqeust comes from a trusted source, only forms from the site are eligable.
Not malicious third-party stuff without a CSRF token.
Let the form pass
In the <form>
element in a Django standard template include {% csrf_token %} tag.
This generates a hidden input field with the CSRF token which is submitted with the form data validating the request.
Example:
<form method="POST" action="{% url 'your-view-url' %}">
{% csrf_token %}
<label for="name">Name:</label>
<input type="text" id="name" name="name">
<button type="submit">Submit</button>
</form>
Testing Methods
If a django site is being run locally for development and an HTTP method is to be tested, open an additional terminal window and execute the following. Input any HTTP method.
For this example POST
will be used:
curl -X POST https://127.0.0.1:8000/
Check the local server running and confirm the output.