# Documentazione Django 5.2.8

# Come usare la protezione CSRF di Django

Per trarre vantaggio dalla protezione di CSRF nelle tue view, segui questi passi:

1. Il middleware CSRF viene attivato di default nell’impostazione `MIDDLEWARE`. Se sovrascrivi quella impostazione, ricorda che `'django.middleware.csrf.CsrfViewMiddleware'` dovrebbe stare prima di ogni middleware per le view che assume che ci si sia già occupati degli attacchi CSRF.

   Se l’hai disabilitato, cosa che non è raccomandata, puoi usare `csrf_protect()` sulle specifiche view che vuoi proteggere (vedi sotto).

2. In ogni template che utilizzi un form POST, usa il tag `csrf_token` dentro l’elemento `<form>` se il form fa riferimento ad un URL interna, per es.:

       <form method="post">{% csrf_token %}

   Questo non si dovrebbe fare per i form POST che hanno come destinazione URL esterne, perchè questo esporrebbe il token CSRF, aprendo una vulnerabilità.

3. Nelle funzioni di view corrispondenti, assicurati che venga utilizzato `RequestContext` per fare render della response così che `{% csrf_token %}` funzioni correttamente. Se stai usando la funzione `render()`, view generiche o app contrib, se già coperto perchè usano già tutte `RequestContext`.

## Utilizzare la protezione CSRF con AJAX

Anche se il metodo di cui sopra può essere utilizzato per le richieste AJAX POST, pone qualche inconveniente: devi ricordare di passare il token CSRF con i dati POST ad ogni richiesta POST. Per questo, esiste un metodo alternativo: in ogni XMLHttpRequest, imposta un header personalizzato `X-CSRFToken` (come specificato nell’impostazione `CSRF_HEADER_NAME`) con il valore del token CSFR. Spesso questo è più semplice, perchè molti framework Javascript offrono hooks che permettono di impostare le intestazioni per ogni richiesta.

Prima di tutto, devi ottenere il token CSRF. Come ottenerlo dipende dal fatto che siano abilitate o meno le impostazioni `CSRF_USE_SESSIONS` e `CSRF_COOKIE_HTTPONLY` .

### Acquisire il token se `CSRF_USE_SESSIONS` e `CSRF_COOKIE_HTTPONLY` sono `False`

La fonte raccomandata dalla quale prendere il token è il cookie `csrftoken`, che sarà impostato se hai abilitato la protezione CSRF per le tue view come delinato precedentemente.

Il token CSFR è chiamato `csrftoken` per impostazione predefinita ma puoi controllare il nome del cookie con l’impostazione `CSRF_COOKIE_NAME`.

Puoi ottenere il token in questo modo:

    function getCookie(name) {
        let cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            const cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i++) {
                const cookie = cookies[i].trim();
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    const csrftoken = getCookie('csrftoken');

Il codice qui sopra può essere semplificato usando la ` libreria JavaScript Cookie <https://github.com/js-cookie/js-cookie/>`_ per rimpiazzare `getCookie`:

    const csrftoken = Cookies.get('csrftoken');

Nota

Il token CSRF è anche presente nel DOM in forma mascherata ma solo se esplicitamente incluso nel template usando `csrf_token`. Il cookie contiene il token canonico, non mascherato. `CsrfViewMiddleware` li accetterà entrambi. In ogni caso, per proteggersi da attacchi BREACH, ci si raccomanda di usare un token mascherato.

Avvertimento

Se la tua view non sta facendo rendering di un template contenente il tag di template `csrf_token`, Django potrebbe non impostare il cookie CSRF. Questo accade di sovente in casi in cui i form sono aggiunti dinamicamente alla pagina. Per affrontare questo caso, Django fornisce un decoratore di view che forza l’impostazione del cookie: `ensure_csrf_cookie()`.

### Acquisire il token se `CSRF_USE_SESSIONS` o `CSRF_COOKIE_HTTPONLY` è `True`

Se attivi `CSRF_USE_SESSIONS` o `CSRF_COOKIE_HTTPONLY`, devi includere il token CSRF nel tuo HTML e leggere il token dal DOM con JavaScript:

    {% csrf_token %}
    <script>
    const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
    </script>

### Impostare il token sulla richiesta AJAX

Infine, avrai bisogno di impostare l’intestazione della tua request AJAX. Usando l’API fetch():

    const request = new Request(
        /* URL */,
        {
            method: 'POST',
            headers: {'X-CSRFToken': csrftoken},
            mode: 'same-origin' // Do not send CSRF token to another domain.
        }
    );
    fetch(request).then(function(response) {
        // ...
    });

## Usare la protezione CSRF nei template Jinja2

Il backend di template di Django `Jinja2` aggiunge `{{ csrf_input }}` al context di tutti i template che è equivalente a `{% csrf_token %}` nel linguaggio di template di Django. Per esempio:

    <form method="post">{{ csrf_input }}

## Usare il metodo decoratore

Piuttosto che inserire `CsrfViewMiddleware` come protezione totale, puoi usare il decoratore `csrf_protect()`, che ha esattamente la stessa funzionalità su particolari view che abbiano bisogno di protezione. Devono essere usati entrambi sulle view che inseriscono il token CSRF in output e su quelle che accettano i dati POST dai form. (Sono spesso le stesse funzioni anche se non è sempre così).

L’uso del decoratore di per sè non è raccomandato poichè se dimentichi di usarlo, ci sarà un buco nella sicurezza. La strategia “a tutto tondo” di usare entrambe va bene ed introdurrà un overhead minimo.

## Gestire le richieste rifiutate

Per impostazione predefinita, una response “403 Forbidden” viene inviata all’utente se la request in ingresso fallisce sui controlli fatti da `CsrfViewMiddleware`. Questo dovrebbe accadere solo se c’è un vero Cross Site Request Forgery o quando, a causa di un errore di programmazione, il token CSRF non è stato incluso nel POST del form.

La pagina di errore, in ogni caso, non è molto amichevole quindi potresti voler fornire la tua per gestire questa condizione. Per fare ciù, imposta il setting `CSRF_FAILURE_VIEW`.

I fallimenti CSRF sono registrati come warning nel logger django.security.csrf.

## Usare la protezione CSRF con il caching

Se il tag di template `csrf_token` è utilizzato da un template (o viene chiamata in qualche modo la funzione `get_token`), `CsrfViewMiddleware` aggiungerà un cookie ed una intestazione `Vary: Cookie` alla response. Questo significa che il middleware si comporterà bene con il middleware di cache se viene usato come suggerito (`UpdateCacheMiddleware` viene prima di tutti gli altri middleware).

In ogni caso, se usi decoratori di cache su view specifiche, il middleware CSRF non sarà ancora in grado di impostare l’intestazione Vary sul cookie CSRF e la response sarà messa in cache senza che ci sia. In questo caso, su qualsiasi view che richieda l’inserimento di un cookie CSRF dovresti usare prima il decoratore `django.views.decorators.csrf.csrf_protect()`:

    from django.views.decorators.cache import cache_page
    from django.views.decorators.csrf import csrf_protect

    @cache_page(60 * 15)
    @csrf_protect
    def my_view(request): ...

Se stai usando view basate su classi, puoi fare riferimento a Decorating class-based views.

## I test e la protezione CSRF

`CsrfViewMiddleware` sarà generalmente un grosso ostacolo nel test delle funzioni delle view, a causa della necessità del token CSRF che deve essere inviato ad ogni richiesta POST. Per questo motivo, il client HTTP di Django per i test è stato modificato per impostare un flag sulle richieste che rilassa il middleware ed il decoratore ``csrf_protect` in modo che non rifiutino più le richieste. In ogni altro aspetto (per es. invio di cookie), si comportano nello stesso modo.

Se, per qualche motivo, vuoi che il client di test esegue i controlli CSRF, puoi creare un’istanza del client di test che imponga i controlli CSRF:

    >>> from django.test import Client
    >>> csrf_client = Client(enforce_csrf_checks=True)

## Casi limite

Alcune view hanno requisiti inusuali, il che significa che non ricadono nei pattern normali qui illustrati. Un certo numero di utility possono essere utili in queste situazioni. Gli scenari in cui potrebbero essere necessarie sono descritti nella seguente sezione.

### Disabilitare la protezione CSRF solo per alcune view

Molte view richiedono la protezione CSRF ma alcune non ne hanno bisogno.

Soluzione: invece che disabilitare il middleware ed applicare `csrf_protect` a tutte le view che ne hanno bisogno, abilita il middleware ed usa `csrf_exempt()`.

### Impostare il token quando non viene usato `CsrfViewMiddleware.process_view()`

Ci sono casi in cui `CsrfViewMiddleware.process_view` potrebbe non aver girato prima della tua view - per esempio gli handler 404 e 500 - ma hai ancora bisogno del token CSRF in un form.

Soluzione: usa `requires_csrf_token()`

### Includere il token CSRF in una view non protetta

Potrebbero esserci alcune view che non sono protette e sono esenti con `csrf_exempt` ma hanno ancora bisogno di includere un token CSRF.

Soluzione: usa `csrf_exempt()` seguito da `requires_csrf_token()` (cioè `requires_csrf_token` dovrebbe essere il decoratore più interno).

### Proteggere una view per un solo percorso

Una view ha bisogno di protezione CSRF solo in alcune condizioni e non deve averlo per tutte le altre.

Soluzione: usa `csrf_exempt()` per l’intera funzione di view e `csrf_protect()` per il percorso che necessita di protezione. Esempio:

    from django.views.decorators.csrf import csrf_exempt, csrf_protect

    @csrf_exempt
    def my_view(request):
        @csrf_protect
        def protected_path(request):
            do_something()

        if some_condition():
            return protected_path(request)
        else:
            do_something_else()

### Proteggere una pagina che usa AJAX senza un form HTML

Una pagina fa una richiesta AJAX e non ha un form HTML con un `csrf_token` che farebbe partire il cookie CSRF.

Soluzione: usa `ensure_csrf_cookie()` sulla view che invia la pagina.

## Protezione CSRF in applicazioni riusabili

Dal momento che è possibile per lo sviluppatore disabilitare `CsrfViewMiddleware`, tutte le view rilevanti nelle app contrib usano il decoratore `csrf_protect` per assicurare la sicurezza di queste applicazioni contro CSRF. Si raccomanda agli sviluppatori di applicazioni riutilizzabili che vogliano le stesse garanzie di usare anche il decoratore `csrf_protect` sulle proprie view.