La protezione CSRF (Cross-Site Request Forgery) è essenziale per impedire che attori malevoli inducano un utente autenticato a eseguire azioni indesiderate su un'applicazione web. In questo articolo vedremo come implementare una protezione CSRF minimale in Java senza l'uso di framework esterni.
1. Concetto di base
Il principio fondamentale è associare un token univoco a ogni sessione utente e verificarlo con ogni richiesta che modifica lo stato (POST, PUT, DELETE). Questo token viene incluso nei moduli HTML come campo nascosto.
2. Generazione del token CSRF
Il token può essere generato una volta per sessione e memorizzato come attributo nella HttpSession
.
public class CsrfTokenUtil {
public static String generateToken() {
return java.util.UUID.randomUUID().toString();
}
}
3. Salvataggio del token nella sessione
Nel filtro o servlet che gestisce le richieste, possiamo inizializzare il token se non già presente.
HttpSession session = request.getSession();
String csrfToken = (String) session.getAttribute("csrfToken");
if (csrfToken == null) {
csrfToken = CsrfTokenUtil.generateToken();
session.setAttribute("csrfToken", csrfToken);
}
4. Inserimento del token nel modulo HTML
Il token viene incluso nei moduli come campo nascosto.
<form action="/submit" method="post">
<input type="hidden" name="csrfToken" value="${csrfToken}" />
<input type="text" name="data" />
<button type="submit">Invia</button>
</form>
Assicurati che ${csrfToken}
sia impostato nel contesto della pagina (ad esempio tramite JSP o un attributo request).
5. Validazione del token alla ricezione
Nel servlet o controller che riceve la richiesta POST, confronta il token fornito con quello salvato nella sessione.
String sessionToken = (String) request.getSession().getAttribute("csrfToken");
String requestToken = request.getParameter("csrfToken");
if (sessionToken == null || !sessionToken.equals(requestToken)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "CSRF token non valido");
return;
}
6. Considerazioni aggiuntive
- Rigenera il token a ogni login o logout per maggiore sicurezza.
- Evita di accettare token tramite URL (GET) o intestazioni HTTP personalizzate, se non strettamente necessario.
- Assicurati che tutte le operazioni sensibili siano protette.
Conclusione
Implementare la protezione CSRF è relativamente semplice ma fondamentale per la sicurezza. Sebbene i framework moderni offrano soluzioni già pronte, comprendere il funzionamento interno consente di adattare la protezione a esigenze specifiche.