📌 Csrf token php: guida completa e sicura

Guida tecnica completa ai CSRF token in PHP: cos’è il Cross-Site Request Forgery, come generare e verificare token sicuri, gestire sessioni, scadenze e best practice reali per la protezione delle web application.

Scudo digitale luminoso con lucchetto protegge un modulo web, tra segni di verifica e simboli di avvertimento.

Autore: Redazione · Creato: 06/02/2026 22:14

CSRF Token in PHP: guida completa e sicura

Le web application moderne devono proteggere le azioni degli utenti autenticati. Una delle vulnerabilità più diffuse è il Cross-Site Request Forgery (CSRF): un attacco in cui un sito malevolo induce il browser di un utente autenticato a inviare richieste non intenzionali verso un’applicazione legittima.

Il CSRF token è una delle difese più solide e universalmente accettate per prevenire questo tipo di attacco, soprattutto quando si gestiscono operazioni che modificano lo stato del sistema.

Cos’è un CSRF Token

Un CSRF token è una stringa crittograficamente sicura, generata dal server e associata alla sessione dell’utente. Il token viene inviato insieme a ogni richiesta sensibile e verificato dal server prima di accettare l’operazione.

Perché il CSRF è pericoloso

  • Sfrutta l’autenticazione già valida dell’utente
  • Non richiede il furto delle credenziali
  • Può modificare dati, impostazioni o eseguire azioni critiche

Modello di funzionamento corretto

  • Generazione del token lato server
  • Inserimento del token nella richiesta
  • Verifica lato server con confronto sicuro
  • Scadenza e rotazione del token

Implementazione in PHP

Gestione sicura della sessione

<?php
session_start();
ini_set('session.cookie_httponly', '1');
ini_set('session.use_strict_mode', '1');
?>

Generazione e verifica del token

<?php
function csrf_generate(): string {
    $token = bin2hex(random_bytes(32));
    $_SESSION['csrf_token'] = $token;
    $_SESSION['csrf_time'] = time();
    return $token;
}

function csrf_verify(string $token, int $ttl = 900): bool {
    if (!isset($_SESSION['csrf_token'], $_SESSION['csrf_time'])) {
        return false;
    }
    if ((time() - $_SESSION['csrf_time']) > $ttl) {
        return false;
    }
    return hash_equals($_SESSION['csrf_token'], $token);
}
?>

Inserimento nel form HTML

<input type="hidden" name="csrf_token"
value="<?= htmlspecialchars(csrf_generate(), ENT_QUOTES) ?>">

Verifica lato server

<?php
if (!csrf_verify($_POST['csrf_token'] ?? '')) {
    http_response_code(400);
    exit('Richiesta non valida');
}
?>

Best practice fondamentali

  • Usare sempre HTTPS
  • Token con scadenza temporale
  • Confronto con hash_equals()
  • Rigenerare il token dopo operazioni critiche
  • Non affidarsi solo a SameSite cookie

CSRF e XSS

Il CSRF token non protegge da vulnerabilità XSS. Se uno script malevolo può essere eseguito nel browser dell’utente, il token può essere letto e riutilizzato. La protezione CSRF deve sempre essere accompagnata da una corretta sanitizzazione dell’output e da politiche CSP.

Conclusione

L’uso corretto dei CSRF token rappresenta uno standard minimo di sicurezza per qualsiasi applicazione PHP moderna. È una difesa semplice, efficace e con un costo implementativo minimo rispetto ai danni potenziali che previene.

Esempio completo: form + verifica CSRF

Di seguito un esempio minimale ma completo che mostra l’intero flusso di protezione CSRF in PHP: generazione del token, inserimento nel form e verifica lato server.

index.php – Pagina con il form

<?php
session_start();
ini_set('session.cookie_httponly', '1');
ini_set('session.use_strict_mode', '1');

function csrf_generate(): string {
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        $_SESSION['csrf_time'] = time();
    }
    return $_SESSION['csrf_token'];
}
?>

<!DOCTYPE html>
<html lang="it">
<head>
    <meta charset="UTF-8">
    <title>Form protetto da CSRF</title>
</head>
<body>

<form method="post" action="process.php">
    <input type="hidden" name="csrf_token"
           value="<?= htmlspecialchars(csrf_generate(), ENT_QUOTES, 'UTF-8') ?>">

    <label>Nome</label>
    <input type="text" name="name" required>

    <button type="submit">Invia</button>
</form>

</body>
</html>

process.php – Verifica del token

<?php
session_start();
ini_set('session.cookie_httponly', '1');
ini_set('session.use_strict_mode', '1');

function csrf_verify(string $token, int $ttl = 900): bool {
    if (!isset($_SESSION['csrf_token'], $_SESSION['csrf_time'])) {
        return false;
    }
    if ((time() - $_SESSION['csrf_time']) > $ttl) {
        return false;
    }
    return hash_equals($_SESSION['csrf_token'], $token);
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    exit('Metodo non consentito');
}

if (!csrf_verify($_POST['csrf_token'] ?? '')) {
    http_response_code(400);
    exit('Richiesta non valida');
}

// Token valido: qui puoi processare i dati
echo 'Form inviato correttamente';

// Rotazione del token dopo l’uso
unset($_SESSION['csrf_token'], $_SESSION['csrf_time']);

 


Questo schema è sufficiente per la maggior parte delle applicazioni PHP classiche e rappresenta una base solida da estendere per casi più complessi (AJAX, più form, token per azione).

Messaggio sponsorizzato
Pubblicità

🔗 Condividi l'articolo:

Autore: Redazione · Creato: 06/02/2026 22:14 · Ultima modifica: 03/09/2026 12:20