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.