La sicurezza del codice non è un optional: è una responsabilità essenziale di ogni sviluppatore. Questo articolo inaugura una serie dedicata a come scrivere codice sicuro, affrontando una delle minacce più diffuse e pericolose nello sviluppo di applicazioni: le SQL Injection.
Cos’è una SQL Injection?
La SQL Injection è un attacco in cui un utente malintenzionato manipola le query SQL inviate a un database attraverso input non controllati.
Questo avviene quando l’applicazione non valida correttamente i dati forniti dall’utente e consente a query malevole di essere eseguite, senza quindi alcun controllo su di esse, con conseguenze potenzialmente devastanti.
Cosa può succedere in caso di SQL Injection?
- Accesso non autorizzato ai dati: Gli attaccanti possono ottenere informazioni sensibili, come credenziali, dati personali o aziendali.
- Manipolazione o cancellazione di dati: Una query malevola potrebbe alterare o eliminare dati cruciali.
- Compromissione del sistema: In alcuni casi, l’attaccante può eseguire comandi di sistema attraverso query SQL.
- Impatto legale e reputazionale: La violazione di dati personali può portare a sanzioni (es. GDPR) e alla perdita di fiducia da parte degli utenti.
Esempio di SQL Injection
Consideriamo un codice vulnerabile a SQL Injection:
String username = request.getParameter("username");
String password = request.getParameter("password");
String query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
Code language: JavaScript (javascript)
Se un utente inserisce come username
:
' OR '1'='1
Code language: JavaScript (javascript)
La query risultante diventa:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = ''
Code language: JavaScript (javascript)
Questa condizione sarà sempre vera, permettendo l’accesso non autorizzato in quanto la condizione ‘1’=’1′ è sempre vera e di conseguenza tutte le condizioni che sono scritte prima o dopo questa OR clause sono inutili, pertanto è stato rotto il meccanismo di controllo su username e password, in questo caso.
Come prevenire le SQL Injection in Java
1. Usa Prepared Statements
I Prepared Statements (o query parametrizzate) evitano che l’input dell’utente venga interpretato come parte del codice SQL.
Esempio corretto:
String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();
Code language: JavaScript (javascript)
In questo caso, qualsiasi input verrà trattato come dato e non come comando SQL.
2. Usa ORM (Object Relational Mapping)
Framework come Hibernate o JPA astraggono le query SQL, riducendo il rischio di SQL Injection.
Esempio con Hibernate:
User user = session.createQuery("FROM User WHERE username = :username AND password = :password", User.class)
.setParameter("username", username)
.setParameter("password", password)
.uniqueResult();
Code language: JavaScript (javascript)
3. Valida l’input
Non fidarti mai dell’input dell’utente. Utilizza librerie per la validazione (es. Apache Commons Validator) e limita i caratteri consentiti.
Esempio:
if (!username.matches("[a-zA-Z0-9_]+")) {
throw new IllegalArgumentException("Username contiene caratteri non validi.");
}
Code language: JavaScript (javascript)
4. Configura correttamente il database
Un database configurato correttamente può limitare i danni di un attacco SQL Injection:
- Usa un account con privilegi limitati per accedere al database.
- Abilita log di sicurezza per monitorare attività sospette.
- Sanitizza i dati memorizzati, per evitare che dati malevoli vengano iniettati in seguito.
5. Usa librerie di sicurezza
Esistono librerie dedicate a proteggere le applicazioni da vulnerabilità comuni:
- OWASP ESAPI: fornisce metodi per validare input e prevenire SQL Injection.
- Spring Security: integra strumenti per proteggere applicazioni Spring, incluso il controllo di accesso al database.
Conclusioni
La SQL Injection è una minaccia reale, ma con le giuste pratiche può essere evitata. L’uso di Prepared Statements, ORM, e la validazione dell’input sono strumenti indispensabili per scrivere codice sicuro.
Nel prossimo articolo di questa serie, approfondiremo un’altra vulnerabilità critica: il Cross-Site Scripting (XSS). Fino ad allora, ricorda: il codice sicuro è la tua prima linea di difesa.