Protezione CSRF
2.5.x ✅ 4.0.x ✅
Gli attacchi Cross-Site Request Forgery (CSRF) inducono gli utenti a eseguire azioni non desiderate su un sito dove sono autenticati. XOOPS fornisce protezione CSRF integrata attraverso la classe XoopsSecurity.
Documentazione Correlata
Sezione intitolata “Documentazione Correlata”- Security-Best-Practices - Guida completa alla sicurezza
- Input-Sanitization - MyTextSanitizer e validazione
- SQL-Injection-Prevention - Pratiche di sicurezza del database
Comprensione degli Attacchi CSRF
Sezione intitolata “Comprensione degli Attacchi CSRF”Un attacco CSRF si verifica quando:
- Un utente è autenticato sul tuo sito XOOPS
- L’utente visita un sito web dannoso
- Il sito dannoso invia una richiesta al tuo sito XOOPS utilizzando la sessione dell’utente
- Il tuo sito elabora la richiesta come se provenisse dall’utente legittimo
La Classe XoopsSecurity
Sezione intitolata “La Classe XoopsSecurity”XOOPS fornisce la classe XoopsSecurity per proteggere dagli attacchi CSRF. Questa classe gestisce i token di sicurezza che devono essere inclusi nei moduli e verificati durante l’elaborazione delle richieste.
Generazione dei Token
Sezione intitolata “Generazione dei Token”La classe di sicurezza genera token univoci archiviati nella sessione dell’utente e che devono essere inclusi nei moduli:
$security = new XoopsSecurity();
// Ottieni il campo di input HTML del token$tokenHTML = $security->getTokenHTML();
// Ottieni solo il valore del token$tokenValue = $security->createToken();Verifica del Token
Sezione intitolata “Verifica del Token”Durante l’elaborazione dell’invio del modulo, verifica che il token sia valido:
$security = new XoopsSecurity();
if (!$security->check()) { redirect_header('index.php', 3, _MD_TOKENEXPIRED); exit();}Utilizzo del Sistema di Token XOOPS
Sezione intitolata “Utilizzo del Sistema di Token XOOPS”Con Classi XoopsForm
Sezione intitolata “Con Classi XoopsForm”Quando utilizzi le classi di modulo XOOPS, la protezione con token è semplice:
// Crea un modulo$form = new XoopsThemeForm('Add Item', 'form_name', 'submit.php');
// Aggiungi elementi del modulo$form->addElement(new XoopsFormText('Title', 'title', 50, 255, ''));$form->addElement(new XoopsFormTextArea('Content', 'content', ''));
// Aggiungi campo token nascosto - INCLUDI SEMPRE QUESTO$form->addElement(new XoopsFormHiddenToken());
// Aggiungi pulsante di invio$form->addElement(new XoopsFormButton('', 'submit', _SUBMIT, 'submit'));Con Moduli Personalizzati
Sezione intitolata “Con Moduli Personalizzati”Per moduli HTML personalizzati che non utilizzano XoopsForm:
// Nel tuo file di modulo o PHP$security = new XoopsSecurity();?><form method="post" action="submit.php"> <input type="text" name="title" /> <textarea name="content"></textarea>
<!-- Includi il token --> <?php echo $security->getTokenHTML(); ?>
<button type="submit">Submit</button></form>Nei Template Smarty
Sezione intitolata “Nei Template Smarty”Quando si generano moduli nei template Smarty:
// Nel tuo file PHP$security = new XoopsSecurity();$GLOBALS['xoopsTpl']->assign('token', $security->getTokenHTML());{* Nel tuo template *}<form method="post" action="submit.php"> <input type="text" name="title" /> <textarea name="content"></textarea>
{* Includi il token *} <{$token}>
<button type="submit">Submit</button></form>Elaborazione dell’Invio del Modulo
Sezione intitolata “Elaborazione dell’Invio del Modulo”Verifica Basica del Token
Sezione intitolata “Verifica Basica del Token”// Nel tuo script di elaborazione del modulo$security = new XoopsSecurity();
// Verifica il tokenif (!$security->check()) { redirect_header('index.php', 3, _MD_TOKENEXPIRED); exit();}
// Il token è valido, elabora il modulo$title = $_POST['title'];// ... continua l'elaborazioneCon Gestione Errori Personalizzata
Sezione intitolata “Con Gestione Errori Personalizzata”$security = new XoopsSecurity();
if (!$security->check()) { // Ottieni informazioni sull'errore dettagliate $errors = $security->getErrors();
// Registra l'errore error_log('CSRF token validation failed: ' . implode(', ', $errors));
// Reindirizza con messaggio di errore redirect_header('form.php', 3, 'Security token expired. Please try again.'); exit();}Per Richieste AJAX
Sezione intitolata “Per Richieste AJAX”Quando si lavora con richieste AJAX, includi il token nella tua richiesta:
// JavaScript - ottieni il token dal campo nascostovar token = document.querySelector('input[name="XOOPS_TOKEN_REQUEST"]').value;
// Includi nella richiesta AJAXfetch('ajax_handler.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: 'action=save&XOOPS_TOKEN_REQUEST=' + encodeURIComponent(token)});// Gestore AJAX PHP$security = new XoopsSecurity();
if (!$security->check()) { echo json_encode(['error' => 'Invalid security token']); exit();}
// Elabora la richiesta AJAXVerifica del Referer HTTP
Sezione intitolata “Verifica del Referer HTTP”Per protezione aggiuntiva, specialmente per richieste AJAX, puoi anche verificare il referer HTTP:
$security = new XoopsSecurity();
// Verifica l'intestazione refererif (!$security->checkReferer()) { echo json_encode(['error' => 'Invalid request']); exit();}
// Verifica anche il tokenif (!$security->check()) { echo json_encode(['error' => 'Invalid token']); exit();}Verifica di Sicurezza Combinata
Sezione intitolata “Verifica di Sicurezza Combinata”$security = new XoopsSecurity();
// Esegui entrambe le verificheif (!$security->checkReferer() || !$security->check()) { redirect_header('index.php', 3, 'Security validation failed'); exit();}Configurazione del Token
Sezione intitolata “Configurazione del Token”Durata del Token
Sezione intitolata “Durata del Token”I token hanno una durata limitata per prevenire attacchi di riproduzione. Puoi configurarla nelle impostazioni XOOPS o gestire i token scaduti elegantemente:
$security = new XoopsSecurity();
if (!$security->check()) { // Il token potrebbe essere scaduto // Rigenera il modulo con un nuovo token redirect_header('form.php', 3, 'Your session has expired. Please submit the form again.'); exit();}Moduli Multipli sulla Stessa Pagina
Sezione intitolata “Moduli Multipli sulla Stessa Pagina”Quando hai più moduli sulla stessa pagina, ognuno dovrebbe avere il suo token:
// Modulo 1$form1 = new XoopsThemeForm('Form 1', 'form1', 'submit1.php');$form1->addElement(new XoopsFormHiddenToken('token1'));
// Modulo 2$form2 = new XoopsThemeForm('Form 2', 'form2', 'submit2.php');$form2->addElement(new XoopsFormHiddenToken('token2'));Best Practices
Sezione intitolata “Best Practices”Usa Sempre i Token per le Operazioni che Modificano lo Stato
Sezione intitolata “Usa Sempre i Token per le Operazioni che Modificano lo Stato”Includi i token in qualsiasi modulo che:
- Crea dati
- Aggiorna dati
- Elimina dati
- Modifica le impostazioni dell’utente
- Esegue qualsiasi azione amministrativa
Non Affidarti Solo alla Verifica del Referer
Sezione intitolata “Non Affidarti Solo alla Verifica del Referer”L’intestazione referer HTTP può essere:
- Rimossa da strumenti di privacy
- Assente in alcuni browser
- Falsificata in alcuni casi
Usa sempre la verifica del token come tua difesa principale.
Rigenera i Token in Modo Appropriato
Sezione intitolata “Rigenera i Token in Modo Appropriato”Considera di rigenerare i token:
- Dopo l’invio riuscito del modulo
- Dopo il login/logout
- A intervalli regolari per sessioni lunghe
Gestisci la Scadenza del Token Elegantemente
Sezione intitolata “Gestisci la Scadenza del Token Elegantemente”$security = new XoopsSecurity();
if (!$security->check()) { // Salva i dati del modulo temporaneamente $_SESSION['form_backup'] = $_POST;
// Reindirizza al modulo con messaggio redirect_header('form.php?restore=1', 3, 'Please resubmit the form.'); exit();}Problemi Comuni e Soluzioni
Sezione intitolata “Problemi Comuni e Soluzioni”Errore Token Non Trovato
Sezione intitolata “Errore Token Non Trovato”Problema: Controllo di sicurezza non riuscito con “token not found”
Soluzione: Assicurati che il campo del token sia incluso nel tuo modulo:
$form->addElement(new XoopsFormHiddenToken());Errore Token Scaduto
Sezione intitolata “Errore Token Scaduto”Problema: Gli utenti vedono “token expired” dopo il completamento del modulo
Soluzione: Considera l’uso di JavaScript per aggiornare periodicamente il token:
// Aggiorna il token ogni 10 minutisetInterval(function() { fetch('refresh_token.php') .then(response => response.json()) .then(data => { document.querySelector('input[name="XOOPS_TOKEN_REQUEST"]').value = data.token; });}, 600000);Problemi di Token AJAX
Sezione intitolata “Problemi di Token AJAX”Problema: Le richieste AJAX non superano la validazione del token
Soluzione: Assicurati che il token sia passato ad ogni richiesta AJAX e verificato lato server:
// Gestore AJAXheader('Content-Type: application/json');
$security = new XoopsSecurity();if (!$security->check(true, false)) { // Non cancellare il token per AJAX http_response_code(403); echo json_encode(['error' => 'Invalid token']); exit();}Esempio: Implementazione Completa del Modulo
Sezione intitolata “Esempio: Implementazione Completa del Modulo”<?phprequire_once dirname(__DIR__) . '/mainfile.php';
$security = new XoopsSecurity();
// Gestisci l'invio del moduloif ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!$security->check()) { redirect_header('form.php', 3, 'Security token expired. Please try again.'); exit(); }
// Elabora l'invio valido $title = $myts->htmlSpecialChars($_POST['title']); // ... salva nel database
redirect_header('success.php', 3, 'Item saved successfully!'); exit();}
// Visualizza il modulo$GLOBALS['xoopsOption']['template_main'] = 'mymodule_form.tpl';include XOOPS_ROOT_PATH . '/header.php';
$form = new XoopsThemeForm('Add Item', 'add_item', 'form.php');$form->addElement(new XoopsFormText('Title', 'title', 50, 255, ''));$form->addElement(new XoopsFormTextArea('Content', 'content', ''));$form->addElement(new XoopsFormHiddenToken());$form->addElement(new XoopsFormButton('', 'submit', _SUBMIT, 'submit'));
$GLOBALS['xoopsTpl']->assign('form', $form->render());
include XOOPS_ROOT_PATH . '/footer.php';#security #csrf #xoops #forms #tokens #XoopsSecurity