Protezione CSRF e XSS in Applicazioni Web: Guida Completa
La sicurezza delle applicazioni web è fondamentale per proteggere i dati degli utenti e garantire la fiducia nel sistema. Due delle minacce più comuni che le applicazioni web devono affrontare sono il Cross-Site Request Forgery (CSRF) e il Cross-Site Scripting (XSS). Questi attacchi possono compromettere seriamente la sicurezza della tua applicazione se non gestiti correttamente. In questa guida, esploreremo cosa sono CSRF e XSS, come funzionano, e come puoi proteggere la tua applicazione da questi attacchi utilizzando tecniche e strumenti efficaci.
Cos’è il CSRF?
Il Cross-Site Request Forgery (CSRF) è un attacco che induce un utente autenticato a eseguire azioni non desiderate su un’applicazione web in cui è autenticato. L’attaccante sfrutta la sessione autenticata dell’utente per inviare richieste malevole all’applicazione.
Come Funziona un Attacco CSRF?
In un attacco CSRF, l’attaccante crea un link o un modulo che, quando cliccato o inviato da un utente autenticato, esegue un’azione sul sito web di destinazione come se fosse stata richiesta dall’utente stesso. Ad esempio, l’attaccante potrebbe inviare una richiesta per trasferire fondi dal conto dell’utente al proprio conto.
Esempio di Attacco CSRF
Supponiamo che un utente sia autenticato su un sito di banking online. Un attaccante potrebbe inviare una richiesta del genere:
<img src="https://bank.example.com/transfer?amount=1000&toAccount=attacker" />
Se l’utente autenticato visita una pagina contenente questo codice, il browser invierà la richiesta al sito di banking, effettuando il trasferimento senza il consenso dell’utente.
Come Proteggersi dal CSRF
1. Token CSRF
Una delle tecniche più efficaci per prevenire attacchi CSRF è l’uso di token CSRF. Un token CSRF è un valore unico generato dal server e associato alla sessione dell’utente. Questo token viene inviato insieme ai moduli e alle richieste POST, e il server lo verifica prima di accettare la richiesta.
Implementazione di un Token CSRF in Express.js
npm install csurf --save
const csrf = require("csurf");
const cookieParser = require("cookie-parser");
app.use(cookieParser());
app.use(csrf({ cookie: true }));
app.get("/form", (req, res) => {
res.render("form", { csrfToken: req.csrfToken() });
});
app.post("/process", (req, res) => {
res.send("Modulo elaborato con successo");
});
Nel template del form (form.ejs
):
<form action="/process" method="POST">
<input type="hidden" name="_csrf" value="<%= csrfToken %>" />
<!-- Altri campi del modulo -->
<button type="submit">Invia</button>
</form>
2. Header Custom
Un’altra tecnica è l’utilizzo di header custom per le richieste AJAX. L’attaccante non può inviare richieste con header personalizzati da un dominio diverso, quindi questo metodo può essere efficace per prevenire CSRF su API RESTful.
app.use((req, res, next) => {
if (
req.method === "POST" &&
req.headers["x-custom-header"] !== "expected-value"
) {
return res.status(403).send("Forbidden");
}
next();
});
3. Verifica del Referer
Verificare il referer della richiesta può essere utile per prevenire attacchi CSRF, ma non è sempre affidabile, poiché alcuni browser o proxy possono omettere o modificare questo header.
Cos’è l’XSS?
Il Cross-Site Scripting (XSS) è un tipo di vulnerabilità che consente agli attaccanti di iniettare codice JavaScript malevolo nelle pagine web visualizzate dagli altri utenti. Gli attaccanti possono utilizzare XSS per rubare cookie, dirottare sessioni o reindirizzare gli utenti a siti malevoli.
Tipi di Attacchi XSS
- XSS Riflesso: Il codice malevolo è incluso nella richiesta HTTP e viene “riflesso” nella risposta immediatamente, come nei risultati di una ricerca.
- XSS Persistente: Il codice malevolo viene memorizzato nel server (ad esempio, in un database) e inviato agli utenti ogni volta che accedono a una determinata pagina.
- XSS DOM-Based: Il codice malevolo viene eseguito direttamente nel browser manipolando il Document Object Model (DOM).
Come Proteggersi dall’XSS
1. Sanificazione dell’Input
Sanificare l’input degli utenti è la difesa principale contro XSS. Questo processo implica la rimozione o l’escape dei caratteri speciali (come <
, >
, "
, '
, /
) che possono essere utilizzati per eseguire JavaScript.
Sanificazione dell’Input in Express.js
Puoi utilizzare librerie come DOMPurify o sanitize-html per sanificare l’input degli utenti.
npm install sanitize-html --save
const sanitizeHtml = require("sanitize-html");
app.post("/submit", (req, res) => {
const sanitizedInput = sanitizeHtml(req.body.userInput);
// Utilizza sanitizedInput in modo sicuro
res.send("Input processato in modo sicuro");
});
2. Escape dell’Output
Anche se l’input è sanificato, è buona pratica eseguire l’escape di qualsiasi dato inserito dall’utente prima di renderizzarlo nel browser.
Esempio di Escape in EJS
<%- escape(userInput) %>
3. Content Security Policy (CSP)
L’implementazione di una Content Security Policy (CSP) è un’ulteriore misura di sicurezza che limita le fonti da cui il browser può caricare script, riducendo il rischio di esecuzione di codice XSS.
Configurazione di CSP in Express.js
app.use((req, res, next) => {
res.setHeader(
"Content-Security-Policy",
"script-src 'self'; object-src 'none';"
);
next();
});
4. HttpOnly e Secure Cookies
Imposta i cookie di sessione con le flag HttpOnly e Secure per prevenire l’accesso ai cookie tramite JavaScript e garantire che vengano trasmessi solo su connessioni HTTPS.
app.use(
session({
secret: "session-secret",
cookie: {
httpOnly: true,
secure: true,
},
})
);
Best Practices Generali per la Sicurezza
- Audit del Codice: Esegui audit di sicurezza regolari per identificare e correggere vulnerabilitĂ .
- Formazione Continua: Assicura che tutti gli sviluppatori siano consapevoli delle migliori pratiche di sicurezza.
- Test di Penetrazione: Esegui test di penetrazione per simulare attacchi reali e migliorare le difese.
- Aggiornamento Costante: Mantieni il software e le librerie aggiornate per evitare vulnerabilitĂ note.
Conclusione
Proteggere le tue applicazioni web da attacchi CSRF e XSS è fondamentale per garantire la sicurezza degli utenti e la loro fiducia. Implementando tecniche come l’uso di token CSRF, la sanificazione dell’input, l’escape dell’output, e la configurazione di una Content Security Policy, puoi ridurre significativamente il rischio di attacchi e proteggere efficacemente la tua applicazione. La sicurezza è un processo continuo, e seguire le best practices delineate in questa guida è un ottimo punto di partenza per costruire applicazioni web robuste e sicure.