Validazione e sanificazione dell'input e come prevenire gli attacchi injection

Scopri come validazione e sanificazione dell'input proteggono i moduli dagli attacchi injection e rendono sicuri i dati.

Bozza

Chi attacca un modulo non lo compila come un visitatore normale. Invia codice pensato per entrare nei tuoi sistemi o rubare dati. Può inviare JavaScript da eseguire nei browser dei visitatori, comandi SQL per danneggiare il tuo database o contenuti dannosi. Validazione e sanificazione dell'input sono le difese che fermano questi attacchi.

Cosa imparerai: che cosa sono validazione e sanificazione dell'input, in cosa si differenziano, come funzionano gli attacchi injection, quali protezioni funzionano per i diversi tipi di dati e come applicarle ai tuoi moduli.

Che cos'è la validazione dell'input?

La validazione dell'input è il controllo che i dati inviati con il tuo modulo abbiano il formato che ti aspetti e rispettino le tue regole. È la prima linea di difesa contro l'input dannoso.

La validazione risponde a domande come: questo è un indirizzo email o un testo a caso? È un numero o una parola? Questo campo è vuoto quando non dovrebbe? Il visitatore ha scritto qualcosa che ha senso per questo campo o qualcosa di sospetto?

Esempi di ciò che controlla la validazione:

  • Un campo email deve contenere una chiocciola (@) e un dominio
  • Un campo telefono deve contenere solo cifre e trattini
  • Un campo numerico non deve contenere lettere
  • Un campo obbligatorio non deve essere vuoto
  • Un campo password deve rispettare la lunghezza minima

La validazione avviene in due punti. Sul dispositivo del visitatore si chiama validazione lato client. Sul tuo server si chiama validazione lato server. La validazione lato client dà un riscontro immediato se il visitatore sbaglia. La validazione lato server è quella che protegge davvero dagli attacchi, perché chi attacca può aggirare i controlli lato client.

Che cos'è la sanificazione dell'input?

La sanificazione è il processo che rimuove o rende innocuo tutto ciò che è pericoloso nell'input dell'utente prima di salvarlo o elaborarlo. Anche se i dati superano la validazione, possono contenere codice o caratteri pensati per fare danni.

Esempi di ciò che fa la sanificazione:

  • Rimuove dai campi di testo i tag HTML come `<script>` e `<img>`
  • Rimuove i caratteri speciali SQL che potrebbero servire a violare i database
  • Applica l'escape ai caratteri speciali, così vengono trattati come testo e non come codice
  • Limita la lunghezza dell'input per evitare attacchi di tipo buffer overflow

Validazione e sanificazione lavorano insieme ma hanno scopi diversi. La validazione controlla che i dati abbiano il formato giusto. La sanificazione toglie tutto ciò che è pericoloso anche se il formato è tecnicamente corretto.

Come funzionano gli attacchi injection

SQL injection

Un attacco SQL injection avviene quando qualcuno inserisce codice SQL in un campo del modulo. Se il codice del tuo modulo non sanifica questo input, il codice SQL viene eseguito sul tuo database.

Esempio: un modulo di accesso chiede un indirizzo email. Invece della sua email, chi attacca invia:

' OR '1'='1

Se il modulo non sanifica l'input, il tuo codice potrebbe eseguire una query SQL come questa:

SELECT * FROM users WHERE email = '' OR '1'='1'

La parte `OR '1'='1'` rende la condizione sempre vera, quindi la query restituisce tutti gli utenti invece di uno solo con quell'email. Chi attacca ha aggirato il sistema di accesso.

Cross-Site Scripting (XSS)

Un attacco XSS avviene quando qualcuno invia codice JavaScript in un campo del modulo. Se il modulo non sanifica questo codice e lo salva, il JavaScript viene eseguito nei browser di chiunque veda quei dati in seguito.

Esempio: un modulo per i commenti accetta i commenti degli utenti. Chi attacca invia:

<script>alert('hacked')</script>

Se non viene sanificato e finisce nel database, quando qualcuno apre la sezione dei commenti il JavaScript viene eseguito e mostra un avviso. Una versione più pericolosa potrebbe rubare i cookie, reindirizzare i visitatori a una pagina di phishing o estrarre i dati dei moduli.

Command injection

Se i dati del tuo modulo vengono usati in comandi di sistema (succede in alcuni sistemi backend), chi attacca può inserire comandi del sistema operativo.

Esempio: un campo del modulo viene usato in un comando come:

ffmpeg -i $filename output.mp4

Se `$filename` non è sanificato e chi attacca invia `;rm -rf /`, il comando diventa:

ffmpeg -i ;rm -rf / output.mp4

Il comando `rm -rf /` viene eseguito e cancella i file dal sistema. Per questo i comandi di sistema non dovrebbero mai ricevere input dell'utente non sanificato.

Validazione e sanificazione per i diversi tipi di dati

Indirizzi email

Validazione: controlla che l'input corrisponda a un formato email (qualcosa come testo@dominio.estensione). Verifica che contenga solo caratteri ammessi.

Sanificazione: rimuovi tag HTML e caratteri speciali. Tieni solo caratteri alfanumerici, punti, trattini e la chiocciola.

Numeri di telefono

Validazione: controlla che contenga solo cifre, trattini, parentesi e spazi. Verifica che la lunghezza sia giusta per il paese previsto.

Sanificazione: rimuovi tutti i caratteri non numerici tranne trattini e parentesi. Elimina zeri iniziali o spazi, se serve.

Campi di testo (commenti, nomi, indirizzi)

Validazione: controlla che il campo non sia vuoto e che la lunghezza sia ragionevole (non milioni di caratteri).

Sanificazione: rimuovi o applica l'escape a tag HTML, JavaScript e caratteri speciali SQL. Tieni solo testo semplice e punteggiatura di base.

Numeri e importi

Validazione: controlla che l'input sia un numero. Per prezzi o quantità, controlla che sia un numero positivo.

Sanificazione: rimuovi tutti i caratteri non numerici. Se serve, arrotonda al giusto numero di decimali.

Password

Validazione: controlla la lunghezza minima (almeno 8 caratteri) e, se vuoi, richiedi un mix di maiuscole, minuscole, numeri e simboli.

Sanificazione: non eliminare né modificare le password. Vanno salvate esattamente come sono (con hash, mai in chiaro). Se togli dei caratteri da una password, gli utenti non riusciranno più ad accedere.

Caricamento di file

Validazione: controlla che il tipo di file sia quello previsto (per esempio solo PDF, solo immagini). Controlla che le dimensioni non siano eccessive.

Sanificazione: rinomina il file, così chi attacca non può sfruttare nomi di file speciali. Analizza il file alla ricerca di malware. Salvalo fuori dalla root del web, così non può essere eseguito come codice.

Come applicare validazione e sanificazione

Lato client (nel browser)

Usa gli attributi di validazione dell'input di HTML5 per dare un riscontro immediato ai visitatori:

<input type="email" name="email" required> <input type="tel" name="phone" pattern="[0-9]{10}"> <input type="number" name="age" min="0" max="120">

Così intercetti gli errori più evidenti e migliori l'esperienza d'uso. Ma la validazione lato client si può aggirare, quindi da sola non è una misura di sicurezza.

Lato server (sul tuo server)

Qui si gioca la sicurezza. Il tuo codice backend deve validare e sanificare ogni dato:

// Esempio in pseudocodice if (email non corrisponde al formato email) { rifiuta l'invio } // Rimuovi i tag HTML sanitized_comment = remove_html_tags(comment_text) // Applica l'escape ai caratteri speciali per il database safe_name = escape_sql_characters(user_name) // Solo dopo salva i dati store_in_database(safe_name, sanitized_comment)

Usa query parametrizzate per i database

La difesa migliore contro la SQL injection sono le query parametrizzate (dette anche prepared statement). Invece di inserire l'input dell'utente direttamente nella query SQL, usi dei segnaposto e passi i dati a parte:

// Sbagliato (vulnerabile): query = "SELECT * FROM users WHERE email = '" + email + "'" // Giusto (sicuro): query = "SELECT * FROM users WHERE email = ?" execute(query, [email])

Con le query parametrizzate, il parser SQL sa che l'input dell'utente sono dati, non codice. Anche se chi attacca invia codice SQL, viene trattato come testo semplice.

Usa librerie e framework

Non scrivere il codice di sanificazione da zero. Usa librerie consolidate pensate per questo scopo. In PHP usa htmlspecialchars() o una libreria come HTML Purifier. In Python usa il modulo `html` o una libreria come bleach. In Node.js usa `express-validator` o simili. Queste librerie sono state testate e vengono aggiornate per gestire nuovi tipi di attacco.

Errori comuni di validazione e sanificazione

Validare solo lato client. La validazione lato client serve all'esperienza d'uso, non alla sicurezza. Chi attacca può aggirarla. Devi validare anche sul server.

Bloccare i caratteri pericolosi invece di ammettere solo quelli sicuri. Se provi a fermare la SQL injection togliendo punti e virgola e apici, chi attacca troverà il modo di aggirarti. Meglio ammettere solo i caratteri che ti aspetti (per i numeri di telefono, solo cifre e trattini) e rifiutare tutto il resto.

Fidarsi del tipo di dato del campo. Se hai un campo numerico, il browser invia testo che somiglia a un numero. Il tuo server deve comunque verificare che sia davvero un numero prima di usarlo. Non dare mai per scontato che il tipo di dato sia corretto.

Dimenticare di sanificare i dati che vengono mostrati. Anche se i dati sono salvati in modo sicuro, se li mostri in una pagina web senza l'escape dell'HTML, chi attacca può inserire codice che viene eseguito nei browser dei visitatori quando vedono quei dati.

Sanificare nell'ordine sbagliato. Prima valida (il formato è giusto?), poi sanifica (è sicuro?). Se sanifichi e poi validi, rischi di rifiutare dati che in realtà erano sicuri.

Cosa fa WEMASY per la validazione dell'input

WEMASY valida i campi del modulo in automatico in base al tipo di campo che scegli. I campi email vengono controllati per verificare che il formato sia valido. I campi numerici vengono controllati per verificare che l'input sia numerico. I campi obbligatori vengono controllati prima dell'invio. Lato server, WEMASY sanifica tutto l'input per rimuovere HTML, JavaScript e altro codice pericoloso prima di salvare le risposte. Tu scegli quali campi raccogliere e WEMASY si occupa di validazione e sanificazione dietro le quinte.

Scopri quali funzioni dei moduli sono incluse nel tuo piano nella pagina dei prezzi.

Domande frequenti

Posso usare un WAF (Web Application Firewall) al posto della validazione?
Un WAF può fermare alcuni attacchi injection prima che arrivino al tuo modulo, ed è utile. Ma non sostituisce validazione e sanificazione. Un WAF è una seconda linea di difesa. Il codice del tuo modulo deve comunque validare e sanificare i dati da solo. Usare insieme WAF e validazione dell'input ti dà più livelli di protezione.
E se un visitatore ha davvero bisogno di inviare caratteri speciali?
Caratteri speciali come apostrofi, trattini e e commerciali sono sicuri se sanifichi correttamente. Per esempio, qualcuno può avere un nome come "O'Brien" o "Mary-Jane". Sono sicuri da accettare se applichi l'escape nel modo giusto per il database (con query parametrizzate) e quando li mostri (con l'escape dell'HTML). Il punto è sanificare bene, non bloccare i caratteri.
Devo validare sia lato client sia lato server?
Sì. La validazione lato client dà ai visitatori un riscontro immediato e migliora l'esperienza (si accorgono di un refuso prima di inviare). La validazione lato server è quella che protegge davvero dagli attacchi. Usa entrambi i livelli. Il lato client serve all'esperienza d'uso. Il lato server serve alla sicurezza.
Qual è la differenza tra escape e sanificazione?
L'escape converte i caratteri pericolosi in modo che vengano trattati come testo semplice (per esempio trasformando < in <). La sanificazione rimuove del tutto il contenuto pericoloso (per esempio eliminando tutti i tag HTML). L'escape conserva i dati, la sanificazione elimina la minaccia. Per la maggior parte dei dati dei moduli, sanificare (togliere del tutto i tag) è più sicuro che applicare l'escape (convertirli).
Devo preoccuparmi degli attacchi injection nei moduli di sola lettura?
Se un modulo si limita a mostrare informazioni (non invia nulla), non ha vulnerabilità injection. Ma se quel modulo mostra mai dati inviati dagli utenti, devi comunque sanificarli. Chi attacca potrebbe aver inviato codice dannoso in precedenza e, quando lo mostri, quel codice viene eseguito. Sanifica sempre tutti i dati inviati dagli utenti prima di mostrarli, qualunque sia il tipo di modulo.

Mettilo in pratica
sul tuo sito web.

Inizia gratis con WEMASY e crea il tuo sito in pochi minuti.