guides-resources

Database Security: Hardening, Misconfigurazioni e Pentest

Database Security: Hardening, Misconfigurazioni e Pentest

Database security per pentester e defender: misconfigurazioni, credenziali deboli, servizi esposti e hardening di MSSQL, MySQL e PostgreSQL.

  • Pubblicato il 2026-08-07
  • Tempo di lettura: 11 min

Database Security: Come Trovare Misconfigurazioni e Proteggere i Database #

Il database è il cuore di qualsiasi applicazione: contiene credenziali, dati personali, transazioni finanziarie e segreti aziendali. Una configurazione debole può esporre direttamente queste informazioni o trasformare un accesso limitato in una compromissione più ampia dell’infrastruttura.

Secondo il Cost of a Data Breach Report 2025 di IBM, il costo medio globale di una violazione dei dati è stato di 4,44 milioni di dollari, in calo del 9% rispetto ai 4,88 milioni del 2024. Porte esposte, credenziali deboli, privilegi eccessivi, autenticazione assente e funzionalità amministrative non necessarie aumentano sensibilmente la superficie d’attacco.

Questa guida copre due prospettive:

  • Pentester/attaccante: come trovare e sfruttare le misconfigurazioni
  • Defender/developer: come configurare correttamente ogni database

Vedi anche: database-privilege-escalation, sql-injection, brute-force, credential-dumping.


Le Misconfigurazioni Più Pericolose (Vista Pentester) #

Prima di entrare nei dettagli per ogni DB, ecco le misconfigurazioni che un pentester cerca per prime — quelle che portano da zero a shell nel minor tempo possibile.

1. Database Esposto su Internet Senza Autenticazione #

È uno degli scenari più pericolosi: il database è raggiungibile da reti non autorizzate e consente operazioni senza un controllo di autenticazione adeguato. MongoDB, Redis, Elasticsearch e altri datastore possono risultare esposti quando vengono usate versioni legacy, immagini preconfigurate insicure oppure quando vengono disabilitati binding locali, protected mode, autenticazione o controlli di rete. Le versioni moderne di questi prodotti non devono essere considerate automaticamente esposte per impostazione predefinita.

bash
# Shodan per trovare DB esposti (in un contesto legale/autorizzato)
# product:MySQL port:3306
# product:PostgreSQL port:5432
# product:"MongoDB" port:27017
# product:Redis port:6379 "OK"

# Nmap per identificare DB esposti nell'infrastruttura target
nmap -sV -p 1433,3306,5432,27017,6379,9200,5984 IP_RANGE
# Vedi anche: nmap (https://hackita.it/articoli/nmap)

# Test accesso Redis senza password
redis-cli -h IP ping
# PONG senza autenticazione indica che almeno il comando PING è consentito.
# Verifica ACL e permessi prima di concludere che tutti i dati siano accessibili.

# Test MongoDB senza auth
mongosh "mongodb://IP:27017" --eval "db.adminCommand('listDatabases')"
# Se restituisce la lista senza credenziali → accesso non autenticato confermato.

# Test Elasticsearch senza auth
curl http://IP:9200/_cat/indices
# Una risposta 200 con la lista degli indici indica accesso non autenticato
# almeno a quell'API; verifica poi i privilegi effettivi di lettura e scrittura.

2. Credenziali Deboli, Riutilizzate o Legacy #

Le versioni moderne dei principali database non devono essere trattate come se avessero una password universale predefinita. Il rischio nasce soprattutto da password vuote, combinazioni deboli, account creati da immagini o appliance di terze parti, credenziali riutilizzate e installazioni legacy. MySQL può essere inizializzato esplicitamente in modalità insicura, SQL Server può avere sa riabilitato in Mixed Mode e Oracle può conservare account legacy non correttamente bloccati.

bash
# Usa questi test solo su sistemi autorizzati e nel rispetto del rate limit.
# Preferisci una wordlist approvata per l'ambiente e combinazioni ricavate
# da documentazione, password policy o credenziali legacy note al cliente.

# Audit controllato MySQL con Hydra
hydra -L utenti_db.txt \
  -P password_approvate.txt \
  -t 2 -W 3 -f IP mysql

# Test manuale MSSQL
impacket-mssqlclient 'sa:PASSWORD_TEST@IP'

# Test manuale MySQL
mysql -h IP -u root -p

# Test manuale PostgreSQL
psql -h IP -U postgres -W

Un’autenticazione riuscita con un account amministrativo e una password debole è un finding grave; il semplice prompt del client non dimostra invece che l’account remoto sia abilitato.

3. Accesso Root/SA da Remoto #

Anche se la password è cambiata, consentire l’accesso dell’utente amministrativo da qualsiasi IP è un rischio enorme.

bash
# MySQL: verifica se root può autenticarsi da remoto
mysql -h IP -u root -p
# Solo una connessione completata con successo conferma l'accesso remoto.
# Il prompt della password viene mostrato dal client prima dell'esito del login.

# MSSQL: SA abilitato e raggiungibile
impacket-mssqlclient 'sa:PASSWORD@IP'

# PostgreSQL: postgres superuser raggiungibile da remoto
psql -h IP -U postgres -c "SELECT version();"

4. Feature Pericolose Abilitate #

bash
# MSSQL: xp_cmdshell abilitata
impacket-mssqlclient 'DOMAIN/USER:PASSWORD@IP' -windows-auth
SQL> SELECT value_in_use FROM sys.configurations WHERE name = 'xp_cmdshell';
# value_in_use = 1 indica che la feature è attiva.
# L'esecuzione richiede comunque i permessi necessari e usa il contesto
# dell'account del servizio SQL Server o di un proxy configurato.

# MySQL: FILE privilege e secure_file_priv
mysql -h IP -u USER -p -e "SHOW GRANTS FOR CURRENT_USER(); SELECT @@secure_file_priv;"
# secure_file_priv = ''   → nessuna restrizione di directory imposta da MySQL
# secure_file_priv = PATH → operazioni file limitate a quella directory
# secure_file_priv = NULL → import/export lato server disabilitato
# Restano sempre necessari FILE privilege e permessi del sistema operativo.

# PostgreSQL: verifica privilegi per programmi lato server
psql -h IP -U USER -c "SELECT current_user, usesuper FROM pg_user WHERE usename=current_user;"
psql -h IP -U USER -c "SELECT pg_has_role(current_user, 'pg_execute_server_program', 'member');"
# COPY ... PROGRAM è riservato ai superuser o ai membri del ruolo
# pg_execute_server_program.
sql
-- Oracle: controlla grant potenzialmente pericolosi assegnati a PUBLIC
SELECT OWNER, TABLE_NAME, PRIVILEGE
FROM DBA_TAB_PRIVS
WHERE GRANTEE = 'PUBLIC'
  AND TABLE_NAME IN ('UTL_FILE','UTL_HTTP','DBMS_SCHEDULER','DBMS_ADVISOR');

5. Dati Sensibili Non Cifrati #

bash
# Cerca colonne con nomi sensibili nel DB (una volta dentro)
# MySQL
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME IN ('password','passwd','pwd','secret','token','api_key',
                      'credit_card','ssn','pin','cvv','private_key')
AND TABLE_SCHEMA NOT IN ('information_schema','mysql','performance_schema');

# PostgreSQL
SELECT table_schema, table_name, column_name
FROM information_schema.columns
WHERE column_name ILIKE ANY(ARRAY['%password%','%secret%','%token%','%api_key%','%credit%'])
AND table_schema NOT IN ('information_schema','pg_catalog');

# Leggi le password: sono in chiaro? MD5? bcrypt?
SELECT username, password FROM users LIMIT 5;
# "password" in chiaro → Critical
# "5f4dcc3b5aa765d61d8327deb882cf99" → MD5 → craccabile in secondi
# "$2b$12$..." → bcrypt → molto più sicuro

MSSQL: Hardening e Misconfigurazioni #

Misconfigurazioni da Cercare #

sql
-- SA abilitato?
SELECT name, is_disabled FROM sys.sql_logins WHERE name = 'sa';
-- is_disabled = 0 → sa è attivo: verifica se è realmente necessario e ben protetto.

-- Autenticazione mista abilitata? (SQL + Windows)
-- Permette login SQL anche se AD è configurato
-- Controlla nelle proprietà del server → Security

-- Database sample installati? (Northwind, pubs, AdventureWorks)
SELECT name FROM sys.databases WHERE name IN ('Northwind','pubs','AdventureWorks');
-- Vanno rimossi in produzione

-- Database con TRUSTWORTHY abilitato?
SELECT name, is_trustworthy_on FROM sys.databases WHERE is_trustworthy_on = 1;
-- Qualsiasi database utente con TRUSTWORTHY = ON deve essere giustificato.
-- Non modificare i database di sistema senza valutarne dipendenze e supporto.

-- CLR Integration abilitata? (esecuzione codice .NET nel DB)
SELECT value FROM sys.configurations WHERE name = 'clr enabled';
-- 1 → abilitata → vettore di exploitation se non necessaria

-- Linked server configurati?
SELECT name, data_source FROM sys.servers WHERE is_linked = 1;
-- Ogni linked server è un potenziale pivot

Hardening MSSQL #

sql
-- 1. Preferisci Windows Authentication e disabilita sa se non necessario
ALTER LOGIN sa DISABLE;
-- Rinominare sa può ridurre il rumore degli attacchi opportunistici,
-- ma non sostituisce password robuste, auditing e limitazioni di rete.

-- 2. Disabilita xp_cmdshell
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 0; RECONFIGURE;

-- 3. Disabilita CLR se non usato
EXEC sp_configure 'clr enabled', 0; RECONFIGURE;

-- 4. Rimuovi TRUSTWORTHY dai DB non necessari
ALTER DATABASE [AppDB] SET TRUSTWORTHY OFF;

-- 5. Usa principio del minimo privilegio
-- Crea un utente dedicato per l'applicazione con solo le permission necessarie
CREATE LOGIN app_user WITH PASSWORD = 'StrongPassword123!';
CREATE USER app_user FOR LOGIN app_user;
GRANT SELECT, INSERT, UPDATE ON SCHEMA::dbo TO app_user;
-- Non dare db_owner o sysadmin all'utente applicativo

-- 6. Configura SQL Server Audit per i login falliti
CREATE SERVER AUDIT [SecurityAudit]
TO FILE (FILEPATH = 'C:\SQLAudit\')
WITH (ON_FAILURE = CONTINUE);
ALTER SERVER AUDIT [SecurityAudit] WITH (STATE = ON);

CREATE SERVER AUDIT SPECIFICATION [LoginAuditSpec]
FOR SERVER AUDIT [SecurityAudit]
  ADD (FAILED_LOGIN_GROUP)
WITH (STATE = ON);
-- La directory deve esistere e l'account del servizio deve poterci scrivere.

→ Vedi anche: porta-1433-mssql


MySQL: Hardening e Misconfigurazioni #

Misconfigurazioni da Cercare #

bash
# Connessione remota root abilitata?
mysql -h IP -u root -p""
# Se entra → root da remoto con password vuota → Critical

# Utenti senza password
mysql -u root -p -e "SELECT user, host, authentication_string FROM mysql.user WHERE authentication_string = '' OR authentication_string IS NULL;"

# Host wildcard (% = qualsiasi IP)
mysql -u root -p -e "SELECT user, host FROM mysql.user WHERE host = '%';"
# user=root host=% → root accessibile da qualsiasi IP → Critical

# FILE privilege (lettura/scrittura file OS)
mysql -u root -p -e "SELECT user, host, File_priv FROM mysql.user;"
# File_priv = Y abilita operazioni sui file compatibilmente con
# secure_file_priv e con i permessi dell'utente di sistema mysqld.

# secure_file_priv
mysql -u root -p -e "SELECT @@secure_file_priv;"
# "" = può leggere/scrivere ovunque
# NULL = disabilitato (sicuro)

# Plugin di autenticazione debole
mysql -u root -p -e "SELECT user, plugin FROM mysql.user;"
# mysql_old_password → hashing debole → craccabile facilmente

Hardening MySQL #

bash
# Usa mysql_secure_installation (wizard di hardening)
mysql_secure_installation
# → Imposta password root
# → Rimuove utenti anonimi
# → Disabilita accesso root remoto
# → Rimuove database di test
sql
-- 1. Elenca gli account anonimi o non necessari
SELECT user, host FROM mysql.user WHERE user = '';
-- Rimuovili con DROP USER usando gli host effettivamente trovati
DROP USER IF EXISTS ''@'localhost';
DROP USER IF EXISTS ''@'%';

-- 2. Elenca gli account root raggiungibili da host non locali
SELECT user, host FROM mysql.user
WHERE user = 'root' AND host NOT IN ('localhost', '127.0.0.1', '::1');
-- Dopo aver verificato che non siano necessari:
-- DROP USER 'root'@'HOST_REMOTO';

-- 3. Rimuovi il database di test se presente e non necessario
DROP DATABASE IF EXISTS test;

-- 4. Crea un account applicativo con privilegi minimi
CREATE USER 'app'@'APP_SERVER_IP' IDENTIFIED BY 'StrongPass123!';
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app'@'APP_SERVER_IP';
-- Niente FILE, SYSTEM_USER, PROCESS o privilegi globali non necessari.

-- 5. Revoca FILE dagli account che non ne hanno bisogno
REVOKE FILE ON *.* FROM 'app'@'APP_SERVER_IP';

Evita di modificare direttamente le grant table con INSERT, UPDATE o DELETE: nelle versioni moderne usa CREATE USER, ALTER USER, DROP USER, GRANT e REVOKE.

ini
# /etc/mysql/mysql.conf.d/mysqld.cnf — configurazione sicura

[mysqld]
# Disabilita connessioni remote (solo localhost)
bind-address = 127.0.0.1

# Disabilita LOAD DATA LOCAL INFILE
local_infile = OFF

# Imposta secure_file_priv per limitare import/export lato server
secure_file_priv = /var/lib/mysql-files/

# Richiedi trasporto cifrato per le connessioni TCP
require_secure_transport = ON

# Mantieni il general query log disabilitato in produzione salvo diagnostica
# temporanea: può avere impatto sulle prestazioni e registrare dati sensibili.
general_log = OFF
log_error = /var/log/mysql/error.log

→ Vedi anche: porta-3306-mysql


PostgreSQL: Hardening e Misconfigurazioni #

Misconfigurazioni da Cercare #

bash
# pg_hba.conf — il file che controlla chi può connettersi e come
# Misconfigurazioni classiche:
cat /etc/postgresql/*/main/pg_hba.conf

# PERICOLOSO: trust da qualsiasi IP (nessuna password richiesta)
# host all all 0.0.0.0/0 trust
# → Chiunque può connettersi senza password

# LEGACY: autenticazione md5 estesa a qualunque rete
# host all all 0.0.0.0/0 md5
# → il supporto agli hash MD5 è deprecato; migra a scram-sha-256
#   e restringi sempre la rete sorgente.

# Test: postgres superuser senza password
psql -h IP -U postgres -c "SELECT version();" 2>&1
# Se entra → trust configurato o password vuota

# Superuser accessibile da remoto
psql -h IP -U postgres -c "SELECT usesuper FROM pg_user WHERE usename=current_user;"
# t → l'account è superuser e può usare COPY ... PROGRAM.
# Il comando viene eseguito come utente del sistema operativo del servizio PostgreSQL.

Hardening PostgreSQL #

bash
# /etc/postgresql/*/main/pg_hba.conf — configurazione sicura
# Formato: TYPE DATABASE USER ADDRESS METHOD

# Permetti solo connessioni locali con scram-sha-256
local   all             postgres                                peer
local   all             all                                     scram-sha-256
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256
# Tutto il resto è rifiutato implicitamente
sql
-- 1. Cambia password del superuser postgres
ALTER USER postgres WITH PASSWORD 'StrongPassword123!';

-- 2. Crea un ruolo applicativo con minimi privilegi
CREATE ROLE app_user LOGIN PASSWORD 'AppPass456!';
GRANT CONNECT ON DATABASE appdb TO app_user;
GRANT USAGE ON SCHEMA public TO app_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_user;
-- Non assegnare SUPERUSER né pg_execute_server_program all'account applicativo.

-- 3. Row Level Security (RLS) per multi-tenant
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY user_orders ON orders
  USING (user_id = current_setting('app.current_user_id')::INTEGER);
-- Ogni utente vede solo i propri record → IDOR database-level prevenuto

-- 4. Revoca ruoli predefiniti ad alto impatto se assegnati per errore
REVOKE pg_read_server_files,
       pg_write_server_files,
       pg_execute_server_program
FROM app_user;

-- 5. Abilita TLS e usa regole hostssl per le connessioni remote
-- In postgresql.conf:
-- ssl = on
-- ssl_cert_file = 'server.crt'
-- ssl_key_file = 'server.key'
-- In pg_hba.conf: usa "hostssl" invece di "host"
ini
# postgresql.conf — parametri di sicurezza chiave
log_connections = on               # logga le connessioni accettate
log_disconnections = on            # logga le disconnessioni
log_statement = 'ddl'              # logga CREATE, DROP e ALTER
log_min_duration_statement = 1000  # logga query più lente di 1 secondo
# Le autenticazioni fallite vengono registrate automaticamente.

→ Vedi anche: porta-5432-postgresql


Regole Universali per Tutti i Database #

Queste si applicano indipendentemente dal tipo di DB.

Principio del Minimo Privilegio #

Ogni utente deve avere solo i permessi strettamente necessari per fare il suo lavoro. L’utente dell’applicazione web non ha bisogno di essere DBA o sysadmin.

sql
-- Sbagliato: utente applicativo con tutti i privilegi
GRANT ALL PRIVILEGES ON *.* TO 'app'@'%';

-- Corretto: solo quello che serve
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.users TO 'app'@'localhost';
GRANT SELECT ON appdb.products TO 'app'@'localhost';
-- Niente DROP, CREATE, ALTER, FILE, SUPER

Non Esporre il DB su Internet #

Il database non dovrebbe essere raggiungibile direttamente da internet salvo un requisito esplicito, documentato e protetto. Deve essere segmentato e accettare connessioni soltanto dagli host e dai servizi autorizzati.

bash
# Verifica le porte in ascolto
ss -tlnp | grep -E "3306|5432|1433|27017|6379"
# Se trovi 0.0.0.0:3306 → MySQL ascolta su TUTTE le interfacce → problema

# Firewall: permetti solo dall'IP dell'application server
iptables -A INPUT -p tcp --dport 3306 -s APP_SERVER_IP -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -j DROP

Cifratura in Transit e at Rest #

bash
# Verifica che la sessione MySQL corrente usi TLS
mysql -h IP -u user -p -e "SHOW STATUS LIKE 'Ssl_cipher';"
# Un valore non vuoto indica che la sessione corrente è cifrata.
# Per imporre TLS lato server: require_secure_transport = ON

# Verifica che la sessione PostgreSQL corrente usi TLS
psql -h IP -U user -c   "SELECT ssl, version, cipher FROM pg_stat_ssl WHERE pid = pg_backend_pid();"
# ssl = t indica una sessione cifrata.

Per la cifratura at rest, usa le funzionalità supportate dal prodotto o dal provider: Transparent Data Encryption, tablespace encryption, cifratura dei volumi, KMS/HSM e gestione centralizzata delle chiavi. Le password applicative non devono essere cifrate in modo reversibile: devono essere trasformate con un algoritmo di password hashing moderno, preferibilmente Argon2id o bcrypt, normalmente a livello applicativo.

Audit Logging #

sql
-- MSSQL: abilita SQL Server Audit
CREATE SERVER AUDIT [SecurityAudit]
TO FILE (FILEPATH = 'C:\Logs\')
WITH (ON_FAILURE = CONTINUE);
ALTER SERVER AUDIT [SecurityAudit] WITH (STATE = ON);

-- MySQL: usa un audit plugin compatibile con la tua edizione oppure
-- centralizza error log e slow query log. Abilita il general query log
-- soltanto per diagnostica temporanea e proteggi i file risultanti.

-- PostgreSQL: pgaudit extension
CREATE EXTENSION pgaudit;
-- In postgresql.conf:
-- pgaudit.log = 'all'  -- logga tutto
-- pgaudit.log = 'ddl,write'  -- logga solo DDL e scritture

Tool per Database Security Assessment #

bash
# SQLMap — SQL injection + enumeration automatica
sqlmap -u "https://target.com/?id=1" --dbs --level=5 --risk=3

# Nessus / OpenVAS — vulnerability scanner per DB
# Lancia una scansione del DB per CVE noti e misconfigurazioni

# lynis — audit di sicurezza generale (include DB)
lynis audit system

# mysqlcheck — verifica integrità DB MySQL
mysqlcheck -u root -p --all-databases

# pg_activity — monitoring real-time PostgreSQL
pip install pg_activity
pg_activity -h IP -U postgres

# Nmap script per enumerazione DB
nmap --script ms-sql-info,ms-sql-empty-password,ms-sql-config IP
nmap --script mysql-info,mysql-empty-password,mysql-databases IP -p 3306
nmap --script pgsql-brute IP -p 5432

# CIS Benchmark scan (per hardening automatizzato)
# Scarica il benchmark per il tuo DB da: https://www.cisecurity.org/cis-benchmarks

Scenari Ricorrenti nei Pentest #

Database esposto per errore di rete: una security group o una regola firewall troppo permissiva rende raggiungibile una porta amministrativa da internet o da segmenti che non dovrebbero accedervi. L’impatto dipende dall’autenticazione, dai privilegi dell’account e dai dati presenti.

Ambiente legacy o di staging dimenticato: un’istanza non inventariata conserva account inutilizzati, password riutilizzate, versioni non supportate o dataset copiati dalla produzione. Questi sistemi sono spesso meno monitorati dell’ambiente principale.

Account applicativo sovraprivilegiato: l’applicazione si collega come DBA, sysadmin o superuser. Una SQL injection o il furto delle credenziali applicative può quindi trasformarsi in accesso completo al database e, quando sono presenti feature pericolose, in esecuzione di comandi sul sistema.

Feature amministrativa non necessaria: xp_cmdshell, ruoli PostgreSQL per l’accesso ai file, privilegi FILE su MySQL o package Oracle assegnati troppo ampiamente aumentano l’impatto di una compromissione. L’escalation a SYSTEM o root non è automatica: dipende dal contesto del servizio, dai privilegi locali e dalle ulteriori misconfigurazioni presenti.


Checklist #

text
RICOGNIZIONE
☐ Porte DB identificate: 1433, 3306, 5432, 27017, 6379, 9200
☐ DB raggiungibile dall'esterno? (non dovrebbe esserlo)
☐ Banner e versione identificati (vulnerabilità note?)
☐ Audit autorizzato delle credenziali deboli o legacy completato con rate limit

AUTENTICAZIONE
☐ Password vuote o default eliminate
☐ Accesso account amministrativi remoti limitati agli host autorizzati
☐ Accesso anonimo o senza password disabilitato
☐ Metodo di autenticazione: scram-sha-256 (PostgreSQL), caching_sha2_password (MySQL)
☐ Password auditing eseguito solo se previsto dalle regole d'ingaggio

AUTORIZZAZIONE
☐ Principio minimo privilegio applicato (utente app ≠ DBA)
☐ MSSQL: sa disabilitato se non necessario
☐ MSSQL: xp_cmdshell disabilitata
☐ MSSQL: TRUSTWORTHY OFF sui DB applicativi
☐ MySQL: FILE privilege revocato agli utenti non-root
☐ MySQL: secure_file_priv impostato a una directory dedicata o a NULL
☐ PostgreSQL: superuser e pg_execute_server_program non usati dall'applicazione
☐ Oracle: PUBLIC non ha EXECUTE su UTL_FILE, UTL_HTTP

RETE
☐ DB non esposto su internet (solo su interfaccia interna)
☐ Firewall permette connessioni DB solo dall'app server
☐ SSL/TLS abilitato per connessioni remote

DATI
☐ Password hashate con algoritmo sicuro (bcrypt, argon2, non MD5)
☐ Dati sensibili cifrati at rest
☐ Colonne con dati PII identificate e protette

AUDIT
☐ Log degli accessi abilitato
☐ Log delle autenticazioni fallite abilitato
☐ Log centralizzato su SIEM esterno (non solo locale)

MANUTENZIONE
☐ DB aggiornato a una release supportata e correttamente patchata
☐ Feature non necessarie disabilitate
☐ Database di test/sample rimossi
☐ Utenti inutilizzati rimossi

FAQ #

Quali misconfigurazioni si incontrano più spesso in un pentest? Tra i problemi ricorrenti ci sono porte raggiungibili da reti troppo ampie, account applicativi sovraprivilegiati, password deboli o riutilizzate, database legacy non inventariati e funzionalità amministrative lasciate attive senza necessità. La frequenza varia molto in base al settore, al prodotto e alla maturità dell’infrastruttura.

Come proteggo un DB già esposto su internet senza downtime? Urgentemente: firewall rule per limitare l’accesso solo agli IP autorizzati. Poi, in un secondo momento: migrazione dell’ascolto su interfaccia interna (bind-address = 127.0.0.1 per MySQL, listen_addresses = 'localhost' per PostgreSQL). Non è possibile farlo senza riavviare il servizio, quindi pianifica una manutenzione breve.

MD5 per le password degli utenti nel DB è ancora accettabile? No. MD5 è un algoritmo veloce e inadeguato per il password hashing: password deboli possono essere recuperate rapidamente con hardware moderno e wordlist. Per le password applicative usa Argon2id, bcrypt o scrypt con parametri adeguati. Per l’autenticazione PostgreSQL migra a scram-sha-256, perché il supporto agli hash MD5 è deprecato.

Devo cifrare i dati at rest? La decisione deve derivare dalla classificazione dei dati, dal threat model, dagli obblighi contrattuali e dalle normative applicabili. Per PII, dati finanziari, sanitari o segreti aziendali la cifratura è normalmente una misura essenziale, ma non sostituisce autorizzazione, segmentazione, auditing e gestione delle chiavi. La cifratura at rest protegge soprattutto supporti, snapshot e backup: non impedisce a un account DB già autorizzato o compromesso di leggere i dati in chiaro.

Qual è la severità di un DB senza autenticazione in un report? Un database raggiungibile senza autenticazione è normalmente High o Critical, ma la severità deve essere motivata con l’impatto reale: esposizione internet, possibilità di lettura o scrittura, sensibilità dei dati, privilegi disponibili e potenziale esecuzione di codice. Un accesso anonimo completo a dati sensibili o a funzioni amministrative giustifica in genere una classificazione Critical.


Risorse #


Un database esposto su internet con credenziali deboli e privilegi eccessivi vale quanto nessuna sicurezza.

#database-security #database-hardening #database-pentesting #mssql-security #mysql-security #postgresql-security #least-privilege

lascia un messaggio

Non sono un robot