00
:
00
:
00
:
00
•Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

CSRF Protection

La protezione CSRF (Cross-Site Request Forgery) e’ una delle funzionalita’ di sicurezza piu’ importanti di Django. Un attacco CSRF avviene quando un sito malevolo induce il browser di un utente autenticato a inviare richieste non autorizzate verso un altro sito. Django previene questo tipo di attacco utilizzando un sistema basato su token.

Cos’e’ un Attacco CSRF

In un attacco CSRF, un aggressore crea una pagina web contenente un form nascosto che punta al tuo sito. Se un utente autenticato visita quella pagina, il form viene inviato automaticamente, eseguendo azioni non desiderate con le credenziali dell’utente. Ad esempio, un trasferimento bancario o un cambio di password.

CsrfViewMiddleware

Django include il CsrfViewMiddleware che verifica automaticamente la presenza e la validita’ di un token CSRF in tutte le richieste POST, PUT, PATCH e DELETE.

# settings.py
MIDDLEWARE = [
    # ...
    'django.middleware.csrf.CsrfViewMiddleware',
    # ...
]

Questo middleware genera un token unico per ogni sessione utente e verifica che le richieste di modifica contengano un token valido.

Il Template Tag csrf_token

Per includere il token CSRF nei form HTML, Django mette a disposizione il template tag {% csrf_token %}. Questo tag deve essere inserito all’interno di ogni form che utilizza il metodo POST.

# template.html
# <form method="post" action="/invia/">
#     {% csrf_token %}
#     <input type="text" name="messaggio">
#     <button type="submit">Invia</button>
# </form>

Il tag genera un campo nascosto nel form contenente il token:

# Output HTML generato:
# <input type="hidden" name="csrfmiddlewaretoken"
#        value="abc123tokenLungoECasuale">

Decoratori per il Controllo CSRF

Django fornisce decoratori per personalizzare il comportamento della protezione CSRF su singole view.

@csrf_exempt

Disabilita la verifica CSRF per una specifica view. Da usare con estrema cautela e solo quando strettamente necessario, ad esempio per endpoint che ricevono richieste da servizi esterni.

from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse

@csrf_exempt
def webhook_esterno(request):
    if request.method == 'POST':
        dati = request.body
        # Elabora i dati dal servizio esterno
        return JsonResponse({'stato': 'ricevuto'})

@csrf_protect

Forza la verifica CSRF su una view specifica, anche se il middleware globale e’ stato disabilitato. Utile per proteggere view critiche.

from django.views.decorators.csrf import csrf_protect

@csrf_protect
def modifica_profilo(request):
    if request.method == 'POST':
        # Questa view e' sempre protetta da CSRF
        request.user.nome = request.POST['nome']
        request.user.save()
        return redirect('profilo')

CSRF nelle Richieste AJAX

Quando si effettuano richieste AJAX (ad esempio con JavaScript Fetch API o librerie come Axios), il token CSRF deve essere incluso manualmente nell’header della richiesta.

Django salva il token CSRF in un cookie chiamato csrftoken. Puoi leggerlo con JavaScript e includerlo nell’header X-CSRFToken.

# Funzione JavaScript per ottenere il cookie CSRF
# function getCookie(name) {
#     let cookieValue = null;
#     if (document.cookie && document.cookie !== '') {
#         const cookies = document.cookie.split(';');
#         for (let cookie of cookies) {
#             cookie = cookie.trim();
#             if (cookie.startsWith(name + '=')) {
#                 cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
#                 break;
#             }
#         }
#     }
#     return cookieValue;
# }
#
# const csrftoken = getCookie('csrftoken');
#
# fetch('/api/endpoint/', {
#     method: 'POST',
#     headers: {
#         'Content-Type': 'application/json',
#         'X-CSRFToken': csrftoken,
#     },
#     body: JSON.stringify({ dato: 'valore' }),
# });

Puoi personalizzare il comportamento del cookie CSRF nelle impostazioni:

# settings.py

# Nome del cookie CSRF
CSRF_COOKIE_NAME = 'csrftoken'

# Durata del cookie in secondi (default: 1 anno)
CSRF_COOKIE_AGE = 31449600

# Invia il cookie solo su HTTPS
CSRF_COOKIE_SECURE = True

# Impedisce l'accesso al cookie da JavaScript (default: False)
CSRF_COOKIE_HTTPONLY = False

# Domini fidati per richieste cross-site
CSRF_TRUSTED_ORIGINS = [
    'https://miosito.com',
    'https://app.miosito.com',
]

Conclusione

La protezione CSRF di Django e’ un meccanismo essenziale per la sicurezza delle applicazioni web. Utilizzare correttamente il template tag {% csrf_token %} nei form, gestire il token nelle richieste AJAX tramite l’header X-CSRFToken e configurare adeguatamente le impostazioni del cookie CSRF sono pratiche fondamentali per prevenire attacchi di falsificazione delle richieste.