djangocsrf

Should the csrf template tag be used in a Search form?


I have a django view that allows a user to search and get data from a database. No changes are made to the database. I also realized that the csrf token shows up in the url. I searched online and read that this shouldn't be the case and that when making GET requests I should not include the csrf token but I am still not sure. Here is my code:

view:

class SearchResultsListView(ListView):
    model = Processor
    template_name = 'finder/search_results.html'
    paginate_by = 10  # Number of results per page

    def get_queryset(self):
        query = self.request.GET.get("q")
        return Processor.objects.filter(
            Q(name__icontains=query) |
            Q(standard_transaction_fee__icontains=query) |
            Q(accepted_payment_methods__icontains=query) |
            Q(available_merchant_countries__icontains=query) |
            Q(supported_business_types__icontains=query) |
            Q(basic_info__icontains=query) |
            Q(restricted_prohibited_business__icontains=query)
           )
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['query'] = self.request.GET.get('q', '')
        return context

html:

<div class="search-container-container">
    <div class="search-results-container">
        <!-- Top search bar -->
        <div class="search-header">
            <form action="{% url 'search_results' %}" method="GET" class="search-search-form">
                {%csrf_token%}
                <input 
                    type="text" 
                    name="q" 
                    class="search-input" 
                    placeholder="Search processors..."
                    value="{{ request.GET.q }}"
                    aria-label="Search"
                >
                <button type="submit" class="search-button">
                    Search
                </button>
            </form>
        </div>

Solution

  • Should the csrf template tag be used in a Search form?

    No, CSRF tokens are used for non-safe methods [mdn-doc], so DELETE, PATCH, POST, and PUT. Django only checks CSRF for these methods, since safe methods are considered not to have side-effects.

    Indeed, in the CsrfViewMiddleware [Django-doc] source code [GitHub], it is always accepted for GET, HEAD, OPTIONS, and TRACE methods:

    class CsrfViewMiddleware(MiddlewareMixin):
        # …
        
        def process_view(self, request, callback, callback_args, callback_kwargs):
            # …
            if request.method in ("GET", "HEAD", "OPTIONS", "TRACE"):
                return self._accept(request)
            # …
        
        # …

    It also makes not much sense to enforce this on a GET request: as said, GET requests are not supposed to create, update or remove data.