SQL – Problemi di sicurezza SQL Injection

()

Ecco una sequenza dettagliata di soluzioni per mitigare il rischio di SQL Injection in un’applicazione che utilizza SQL:

1. Utilizzare Query Parametrizzate (Prepared Statements)

🔍 Perché è importante?

Le query SQL dinamiche concatenano direttamente gli input utente alla query, permettendo a un attaccante di inserire codice malevolo.

🔴 Esempio di codice vulnerabile (Python + SQLite)

pythonCopia codiceusername = input("Inserisci il nome utente: ")
query = "SELECT * FROM utenti WHERE username = '" + username + "'"
cursor.execute(query)  # ❌ VULNERABILE A SQL INJECTION!

Se l’utente inserisce:

bashCopia codice' OR '1'='1

La query diventa:

sqlCopia codiceSELECT * FROM utenti WHERE username = '' OR '1'='1'

E l’attaccante ottiene tutti gli utenti del database.

Soluzione: Query parametrizzate
I Prepared Statements separano la query dai dati, evitando l’iniezione SQL.

pythonCopia codiceimport sqlite3

conn = sqlite3.connect("database.db")
cursor = conn.cursor()

username = input("Inserisci il nome utente: ")
query = "SELECT * FROM utenti WHERE username = ?"
cursor.execute(query, (username,))  # ✅ SICURO!

result = cursor.fetchall()
print(result)

conn.close()

🔵 Vantaggi:
✔ I parametri vengono trattati come dati e non come codice SQL.
✔ Gli attacchi basati su SQL Injection non funzionano.


2. Utilizzare ORM (Object-Relational Mapping)

🔍 Perché è importante?

Un ORM gestisce l’accesso al database in modo sicuro, astrarre le query SQL e prevenire errori umani che portano a vulnerabilità.

Esempio con SQLAlchemy (Python)

pythonCopia codicefrom sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from models import Utente  # Classe ORM per la tabella utenti

engine = create_engine("sqlite:///database.db")
Session = sessionmaker(bind=engine)
session = Session()

username = input("Inserisci il nome utente: ")
utente = session.query(Utente).filter_by(username=username).first()

print(utente)

🔵 Vantaggi:
✔ Genera query sicure automaticamente.
✔ Protegge da SQL Injection.
✔ Fornisce funzioni avanzate per la gestione dei dati.


3. Convalidare e Sanificare gli Input Utente

🔍 Perché è importante?

Se il database accetta input arbitrari, un attaccante può manipolare la query. Validare e sanificare l’input evita questo rischio.

Soluzione: Validazione con regex in Python

pythonCopia codiceimport re

def valida_username(username):
    return re.match(r"^[a-zA-Z0-9_]{3,20}$", username) is not None

username = input("Inserisci il nome utente: ")
if valida_username(username):
    print("Input valido")
else:
    print("Formato non valido")

🔵 Vantaggi:
✔ Permette solo caratteri accettabili (es. lettere, numeri, underscore).
✔ Evita caratteri pericolosi come ', --, ;, ".


4. Limitare i Privilegi del Database

🔍 Perché è importante?

Se l’account del database ha troppi privilegi, un attacco SQL Injection potrebbe distruggere o modificare dati sensibili.

Soluzione: Creare un account con privilegi minimi
In MySQL:

sqlCopia codiceCREATE USER 'app_user'@'localhost' IDENTIFIED BY 'password_sicura';
GRANT SELECT, INSERT, UPDATE ON nome_database.* TO 'app_user'@'localhost';
FLUSH PRIVILEGES;

🔵 Vantaggi:
✔ Anche se un attaccante ottiene accesso, non può eliminare il database.


5. Utilizzare un Web Application Firewall (WAF)

🔍 Perché è importante?

Un WAF protegge da attacchi comuni prima che raggiungano il database.

Soluzione: Usare ModSecurity con Apache/Nginx

  • Apache
bashCopia codicesudo apt install libapache2-mod-security2
sudo a2enmod security2
sudo systemctl restart apache2
  • Nginx
bashCopia codicesudo apt install libnginx-mod-security

🔵 Vantaggi:
✔ Blocca tentativi di SQL Injection in tempo reale.
✔ Protegge anche da altri attacchi web (XSS, CSRF).


6. Evitare l’Output di Errori del Database

🔍 Perché è importante?

Se il database mostra errori dettagliati, un attaccante può dedurre la struttura delle tabelle.

Soluzione: Disabilitare il debug in produzione

  • In PHP:
phpCopia codiceini_set('display_errors', 0);
  • In Django (Python):
pythonCopia codiceDEBUG = False

🔵 Vantaggi:
✔ Nasconde informazioni sensibili agli attaccanti.


7. Usare Stored Procedures Sicure

🔍 Perché è importante?

Le Stored Procedures predefiniscono le query SQL, impedendo la modifica dinamica delle istruzioni SQL.

Esempio in SQL Server

sqlCopia codiceCREATE PROCEDURE GetUtente
    @username NVARCHAR(50)
AS
BEGIN
    SELECT * FROM utenti WHERE username = @username
END

E nel codice Python:

pythonCopia codicecursor.execute("EXEC GetUtente @username = ?", (username,))

🔵 Vantaggi:
✔ Il database esegue solo query predefinite.
✔ Non è possibile alterare dinamicamente la query.


8. Monitorare e Loggare le Attività

🔍 Perché è importante?

I log aiutano a rilevare tentativi di attacco.

Soluzione: Abilitare il log delle query sospette

  • MySQL
sqlCopia codiceSET GLOBAL general_log = 'ON';
  • PostgreSQL
sqlCopia codiceALTER SYSTEM SET log_statement = 'all';

🔵 Vantaggi:
✔ Permette di rilevare e bloccare attacchi in tempo reale.


9. Crittografare i Dati Sensibili

🔍 Perché è importante?

Se un hacker accede al database, le password devono rimanere illeggibili.

Soluzione: Hashing con bcrypt in Python

pythonCopia codiceimport bcrypt

password = "password123"
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())

print(hashed)  # Salva solo l'hash nel database

🔵 Vantaggi:
✔ Anche se il database viene compromesso, le password rimangono protette.


🔹 Conclusione

Le misure più efficaci per prevenire SQL Injection sono:

Query Parametrizzate
Uso di ORM
Validazione dell’input
Limitazione dei privilegi del database
Uso di un WAF

/ 5
Grazie per aver votato!

How useful was this post?

Click on a star to rate it!

Average rating / 5. Vote count:

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?