Non serve adottare tutti e quattro i tipi di scansione lo stesso mese. Se il team è piccolo, parti da SCA e secrets scanning: sono i più economici da attivare, richiedono poca configurazione e coprono due categorie salite molto in classifica nella OWASP Top 10 2025, A02 e A03. SAST e DAST hanno una curva di adozione più lunga perché generano più falsi positivi all’inizio, ma diventano indispensabili man mano che l’applicazione cresce e il codice passa per più mani diverse.
Tabella riassuntiva: le 10 categorie e le azioni di remediation
| Categoria 2025 | Posizione 2021 | Posizione 2025 | Azione di remediation principale |
|---|---|---|---|
| A01 Broken Access Control | 1 | 1 | Middleware di autorizzazione per oggetto e ruolo, include SSRF |
| A02 Security Misconfiguration | 5 | 2 | Helmet, disabilitare debug e header verbosi |
| A03 Software Supply Chain Failures | Nuova | 3 | SBOM, npm audit, pin delle versioni dei tool |
| A04 Cryptographic Failures | 2 | 4 | TLS 1.3, Argon2id per l’hashing |
| A05 Injection | 3 | 5 | Query parametrizzate, validazione input |
| A06 Insecure Design | 4 | 6 | Threat modeling rapido per ogni feature |
| A07 Authentication Failures | 7 | 7 | Rate limiting sul login, MFA verificato lato server |
| A08 Software or Data Integrity Failures | 8 | 8 | Verifica firme e checksum dei pacchetti |
| A09 Security Logging & Alerting Failures | 9 | 9 | Error handler centralizzato, log senza dati sensibili |
| A10 Mishandling of Exceptional Conditions | Nuova | 10 | Fail closed sugli errori, gestione esplicita dei casi limite |
Errori comuni da evitare nella remediation OWASP Top 10
Anche seguendo tutti i dieci passi di questa guida, alcuni errori ricorrono spesso nei team che affrontano la remediation per la prima volta. Sono quasi sempre errori di processo più che di codice, e per questo passano inosservati finché non causano un incidente o un audit fallito.
- Trattare la Top 10 come una checklist statica. Le categorie descrivono classi di rischio, non singoli bug: un middleware di autorizzazione copre decine di endpoint diversi, non uno solo.
- Aggiungere Helmet senza configurare la CSP. I valori di default sono un buon punto di partenza, ma una Content Security Policy troppo permissiva vanifica gran parte del beneficio contro A02.
- Ignorare gli aggiornamenti dei tool di sicurezza stessi. L’incidente Trivy di marzo 2026 dimostra che anche gli strumenti di scansione possono diventare un vettore di attacco alla supply chain.
- Loggare troppo o troppo poco. Un log che include password o token in chiaro crea un nuovo problema di A09; un log troppo scarno rende impossibile l’incident response quando serve davvero.
- Rimandare la remediation di A06 Insecure Design a dopo il rilascio. Le scelte architetturali sono le più costose da correggere retroattivamente: vanno discusse prima di scrivere codice, non dopo.
- Applicare rate limiting solo sul login e dimenticare gli endpoint di reset password. Sono spesso il bersaglio più semplice per un attacco di enumerazione utenti.
Nessuno di questi errori richiede uno strumento nuovo per essere evitato: bastano una revisione del codice più attenta e una checklist condivisa da consultare prima di ogni rilascio, come quella riassunta nella tabella di questa guida.
Risoluzione dei problemi comuni (troubleshooting)
Durante l’applicazione dei dieci passi capita di incontrare errori che non dipendono dalla logica di remediation in sé, ma dall’integrazione con l’ambiente esistente. Ecco le situazioni più frequenti segnalate da chi ha già seguito questo tipo di percorso, con la causa più probabile e la soluzione diretta.
- Helmet blocca il caricamento di script esterni necessari. Aggiungi il dominio specifico a
scriptSrcnella Content Security Policy invece di disattivarla del tutto. - npm audit segnala vulnerabilità in una dipendenza transitiva senza fix disponibile. Usa
npm ls nome-pacchettoper capire chi la richiede e valuta un override temporaneo tramite il campooverridesinpackage.json. - argon2 fallisce l’installazione su alcuni ambienti CI. Il pacchetto compila un binding nativo: verifica che l’immagine CI includa i build tools richiesti oppure usa l’immagine ufficiale Node già pronta.
- Il rate limiter blocca utenti legittimi dietro lo stesso IP aziendale (NAT). Passa a una chiave combinata IP più identificativo utente invece del solo indirizzo IP.
- Trivy restituisce falsi positivi su pacchetti già corretti a runtime. Aggiorna il database delle vulnerabilità con
trivy image --download-db-onlyprima di ogni scansione programmata. - Le sessioni scadono troppo in fretta dopo l’attivazione di HSTS. HSTS riguarda solo il trasporto: se le sessioni scadono, controlla la configurazione del cookie di sessione, non l’header di sicurezza.
- La pipeline CI fallisce solo in produzione, non in locale. Controlla che le variabili d’ambiente richieste dal middleware di sicurezza siano definite anche nei secret della pipeline, non solo nel file
.envlocale. - Il threat model per A06 non converge mai su una decisione. Fissa un timebox di 30-45 minuti per sessione e documenta le decisioni prese anche se parziali: un threat model incompleto ma scritto vale più di uno perfetto mai concluso.
Consigli avanzati per team DevSecOps
Una volta completata la remediation di base, alcuni accorgimenti aggiuntivi alzano ulteriormente il livello di sicurezza senza stravolgere il workflow del team. Integra la scansione SBOM direttamente nel merge request, non solo nella pipeline notturna: un blocco immediato su una dipendenza critica costa molto meno di una scoperta a distanza di settimane. Ruota le chiavi API e i secret con una cadenza fissa, anche in assenza di un incidente noto, e automatizza la rotazione dove possibile invece di affidarti a un promemoria manuale.
Per team più maturi, vale la pena mappare esplicitamente ogni categoria della OWASP Top 10 2025 sui controlli richiesti dalla direttiva NIS2, così un singolo intervento di remediation copre due esigenze insieme: sicurezza tecnica e conformità normativa. Infine, tieni traccia delle metriche di remediation nel tempo, come il numero di vulnerabilità high o critical aperte per categoria: è un indicatore molto più utile del solo conteggio totale delle vulnerabilità.
Un ultimo consiglio riguarda la formazione del team: la remediation tecnica dura poco se chi scrive codice nuovo ogni giorno non capisce perché un certo pattern è vietato. Dedica una sessione breve, anche di 30 minuti al mese, a rivedere insieme un caso reale come CVE-2025-8850 o l’incidente Trivy di marzo 2026, invece di limitarti a distribuire un documento di policy che nessuno rilegge dopo la prima settimana.
NIS2, ENISA e conformità europea
Per le aziende italiane ed europee la remediation OWASP non è solo una questione tecnica. La direttiva NIS2 richiede alle entità essenziali e importanti di dimostrare misure di sicurezza allineate allo stato dell’arte, e diversi fornitori di sicurezza citano proprio la OWASP Top 10:2025 come base tecnica di riferimento per questo requisito. ENISA, l’agenzia europea per la cybersicurezza, pubblica linee guida complementari che si sovrappongono in larga parte alle stesse dieci categorie.
Nella pratica, un audit NIS2 non chiede di citare letteralmente “OWASP Top 10” in un documento, ma di dimostrare un processo di gestione del rischio applicativo continuo e documentato. Il SBOM generato al passo 4, i log strutturati del passo 9 e la pipeline CI del passo 10 diventano evidenze concrete da mostrare durante un audit, molto più convincenti di una policy scritta ma mai applicata nei repository reali.
| Ambito di conformità | Riferimento | Collegamento con la OWASP Top 10 2025 |
|---|---|---|
| Direttiva NIS2 | Entità essenziali e importanti UE | Base tecnica per dimostrare misure allo stato dell’arte |
| Linee guida ENISA | Agenzia europea cybersicurezza | Copertura complementare su gestione del rischio |
| Cyber Resilience Act | Prodotti con elementi digitali | Richiede SBOM e gestione vulnerabilità, in linea con A03 |
Per un team italiano che vende software con componenti digitali in Europa, il Cyber Resilience Act aggiunge un obbligo diretto di gestione delle vulnerabilità lungo tutto il ciclo di vita del prodotto, non solo al momento del rilascio iniziale. Il SBOM generato al passo 4 e la pipeline di scansione del passo 10 non sono quindi solo buone pratiche tecniche: diventano la base documentale su cui costruire la conformità richiesta dal regolamento, con il vantaggio di essere già automatizzate invece di dipendere da un controllo manuale periodico.
Domande frequenti
Quanto tempo serve per applicare la remediation completa della OWASP Top 10:2025?
Per un’applicazione media, seguendo i dieci passi di questa guida, il lavoro tecnico richiede tra le 8 e le 16 ore, distribuite su più giorni per lasciare spazio ai test. La parte più lunga di solito è il threat modeling di A06, non la scrittura del codice. Su un’applicazione legacy di grandi dimensioni, con molte route non documentate, il tempo può salire di parecchio: in quel caso conviene affrontare prima A01 e A02, che coprono la superficie di attacco più ampia con il minor sforzo iniziale.
La OWASP Top 10 2025 sostituisce completamente quella del 2021?
Sì, OWASP la presenta come la versione corrente e di riferimento. La versione 2021 resta consultabile per motivi storici, ma i nuovi progetti dovrebbero partire direttamente dalla struttura A01-A10 del 2025.
Devo usare per forza Node.js ed Express per applicare questa guida?
No. Gli esempi di codice usano Node.js perché è uno stack comune, ma ogni categoria ha equivalenti diretti in altri linguaggi: Spring Security per Java su A01, Django ORM per la parametrizzazione delle query su A05, e così via.
Perché Security Misconfiguration è salita così tanto in classifica?
Perché l’adozione di cloud, container e pipeline CI/CD ha moltiplicato i punti in cui una configurazione può essere lasciata troppo permissiva, mentre le classi di vulnerabilità più “classiche” come injection sono oggi meglio comprese e più spesso intercettate da strumenti automatici.
Cos’è esattamente un SBOM e perché serve per A03?
Un SBOM (Software Bill of Materials) è un elenco strutturato di tutte le dipendenze usate da un’applicazione, comprese quelle indirette. Serve a sapere, in caso di una nuova vulnerabilità pubblicata, se e dove il progetto è esposto senza dover controllare manualmente ogni pacchetto. I due formati più diffusi sono CycloneDX e SPDX: entrambi vanno bene per iniziare, la scelta conta meno rispetto al fatto di generarlo e conservarlo davvero ad ogni release.
argon2 è davvero meglio di bcrypt per l’hashing delle password?
Argon2id è il vincitore della Password Hashing Competition ed è oggi la raccomandazione di riferimento per nuovi progetti. bcrypt resta accettabile su sistemi legacy, ma per un nuovo sviluppo conviene partire direttamente da argon2id.
Come si collega A10 Mishandling of Exceptional Conditions all’incident response?
Una gestione degli errori che segue il principio “fail closed” riduce il numero di incidenti che arrivano fino al SOC, perché molte condizioni anomale vengono bloccate automaticamente invece di essere silenziosamente concesse.
Serve rifare tutta la remediation a ogni nuova edizione della OWASP Top 10?
No, ma conviene rivedere il mapping tra categorie vecchie e nuove, come nella tabella di questa guida, e verificare se i controlli esistenti coprono ancora le categorie che hanno cambiato definizione, in particolare A03 e A10.
Related Coverage
- OWASP Top 10 2025 vs API Security Top 10: 10 vs 10
- SBOM e Dependency Scan in Node.js: 12 Step, 40 Min
- CISA KEV: 16 Falle in 3 Settimane, 4 Critiche
- Wiz vs Orca Security: Minuti vs 24 Ore di Scansione
- SMS vs App vs Passkey vs Chiave Hardware: 5 Miliardi Attive
Per altri approfondimenti sulla sicurezza applicativa, consulta la sezione Sicurezza di shattered.io.
Verifica ogni installazione con il relativo comando --version prima di procedere: una versione di Node.js troppo vecchia può far fallire silenziosamente l’installazione di argon2, che compila un binding nativo in fase di npm install. Se lavori in team, annota le versioni scelte in un file .nvmrc o equivalente, così ogni sviluppatore parte dallo stesso ambiente e i problemi di compatibilità non si manifestano solo in CI.
Non serve un cluster Kubernetes né un ambiente cloud per seguire la guida: tutto gira in locale su una singola macchina, in modo da isolare la logica di remediation dal rumore dell’infrastruttura.
Se il tuo progetto reale usa un linguaggio diverso da Node.js, mantieni comunque la stessa sequenza di passi: cambia solo la libreria da installare per ogni categoria. In Java lo strato di autorizzazione arriva tipicamente da Spring Security, in Python da un middleware Django o FastAPI dependency, in PHP da un pacchetto come Symfony Security. I nomi cambiano, ma il ragionamento dietro ogni fix resta identico da uno stack all’altro, ed è proprio questo ragionamento l’obiettivo principale della guida.
Passo 1 – Creare il progetto demo da mettere in sicurezza
Il primo passo crea uno scheletro di API volutamente permissivo, che useremo come base per applicare ogni fix. Apri il terminale e lancia questi comandi.
mkdir owasp-remediation-lab && cd owasp-remediation-lab
npm init -y
npm install express helmet argon2 dotenv pg express-rate-limit pino
npm install --save-dev eslint
Struttura del progetto
Organizza le cartelle così, separando configurazione, middleware e route fin dall’inizio: mescolare tutto in un unico file rende la remediation molto più lenta man mano che il progetto cresce.
owasp-remediation-lab/
src/
config/
middleware/
routes/
server.js
.env
package.json
Con la struttura pronta, i prossimi dieci passi affrontano una categoria della OWASP Top 10 2025 alla volta, dalla più critica alla meno urgente secondo il nuovo ordinamento.
Passo 2 – A01 Broken Access Control: middleware di autorizzazione
Broken Access Control resta la categoria numero uno e ora include esplicitamente SSRF, BOLA (Broken Object Level Authorization) e BFLA (Broken Function Level Authorization). La remediation pratica parte da un middleware che verifica proprietà e ruolo su ogni oggetto, non solo l’autenticazione dell’utente.
// src/middleware/authorize.js
function authorize(requiredRole) {
return (req, res, next) => {
const user = req.user;
if (!user) {
return res.status(401).json({ error: 'Autenticazione richiesta' });
}
if (user.role !== requiredRole && user.role !== 'admin') {
return res.status(403).json({ error: 'Accesso negato' });
}
next();
};
}
function ownsResource(getOwnerId) {
return async (req, res, next) => {
const ownerId = await getOwnerId(req.params.id);
if (ownerId !== req.user.id && req.user.role !== 'admin') {
return res.status(403).json({ error: 'Risorsa non tua' });
}
next();
};
}
module.exports = { authorize, ownsResource };
Il caso reale da conoscere qui è CVE-2025-8850, un difetto di design nell’API di LibreChat 0.7.9 che permetteva di disattivare la verifica a due fattori senza i controlli di autorizzazione corretti. È l’esempio perfetto di come A01 e A07 finiscano per intrecciarsi: un endpoint di gestione account senza controllo di ownership diventa un modo per bypassare il secondo fattore.
Nota che ownsResource richiede una funzione asincrona che recuperi il proprietario reale della risorsa dal database, non un valore già presente nella richiesta. Fidarsi di un ownerId passato dal client nel body o nella query string riapre esattamente lo stesso buco che il middleware dovrebbe chiudere: l’unica fonte affidabile è sempre il record salvato lato server. Applica questo middleware su ogni route che espone o modifica un oggetto identificato da ID, comprese quelle interne usate solo dal pannello di amministrazione.
Passo 3 – A02 Security Misconfiguration: hardening con Helmet
Security Misconfiguration è la categoria che è salita di più nella nuova classifica, dal quinto al secondo posto. Riguarda porte di debug lasciate aperte, messaggi di errore troppo verbosi, permessi cloud troppo larghi e header HTTP mancanti. La remediation più rapida per un’app Express è Helmet, che imposta un set di header sicuri con poche righe.
// src/server.js
const express = require('express');
const helmet = require('helmet');
require('dotenv').config();
const app = express();
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
objectSrc: ["'none'"],
},
},
hsts: { maxAge: 63072000, includeSubDomains: true, preload: true },
}));
app.disable('x-powered-by');
app.set('trust proxy', 1);
if (process.env.NODE_ENV === 'production') {
app.use((req, res, next) => {
if (!req.secure) return res.redirect(`https://${req.headers.host}${req.url}`);
next();
});
}
Verifica l’effetto con una chiamata curl prima e dopo l’attivazione di Helmet: la differenza negli header di risposta è immediata.
$ curl -I http://localhost:3000/
# Prima di Helmet
HTTP/1.1 200 OK
X-Powered-By: Express
# Dopo Helmet
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'
Un altro punto della remediation A02 riguarda i segreti: nessuna chiave API o password deve stare nel codice sorgente. Usa sempre variabili d’ambiente caricate da un file .env escluso da git tramite .gitignore.
Ricorda anche di disattivare i messaggi di stack trace dettagliati quando NODE_ENV è impostato su production: molti framework, incluso Express, mostrano per default informazioni interne utili in sviluppo ma pericolose se esposte a un utente reale. Un errore 500 in produzione deve restituire un messaggio generico, mentre il dettaglio completo resta solo nei log interni, gestiti al passo 9 di questa guida.
Passo 4 – A03 Software Supply Chain Failures: SBOM e npm audit
A03 è una delle due categorie completamente nuove della OWASP Top 10 2025. Amplia la vecchia “Vulnerable and Outdated Components” per coprire l’intera catena: dipendenze, sistemi di build, pipeline CI/CD e distribuzione del pacchetto finale. Il primo passo di remediation è generare un SBOM (Software Bill of Materials) e integrarlo nella pipeline.
# Audit rapido delle dipendenze npm
npm audit --omit=dev
# Generazione di un SBOM in formato CycloneDX con Trivy
trivy fs --format cyclonedx --output sbom.json .
# Scansione delle vulnerabilità note sul SBOM appena generato
trivy sbom sbom.json --severity CRITICAL,HIGH
Un esempio concreto del perché questa categoria pesa così tanto: nel marzo 2026 Trivy stesso è stato colpito da un attacco alla supply chain, con una release v0.69.4 compromessa e immagini Docker Hub corrispondenti anch’esse manomesse, come documentato da GitLab nella loro analisi della OWASP Top 10 2025. La lezione pratica è semplice: fissa (pin) le versioni dei tool di sicurezza, verifica gli hash dei binari scaricati e non aggiornare mai automaticamente in produzione senza controllo.
Un SBOM in formato CycloneDX o SPDX serve anche per un secondo motivo, oltre alla scansione: quando una nuova CVE viene pubblicata su una libreria diffusa, puoi rispondere in minuti alla domanda “siamo esposti?” facendo una ricerca sul file invece di controllare manualmente ogni progetto attivo in azienda. Conserva il SBOM generato ad ogni release insieme al tag di versione, così hai uno storico consultabile in caso di audit o di un incidente scoperto mesi dopo.
Passo 5 – A04 Cryptographic Failures: TLS e hashing con Argon2
Cryptographic Failures scende dal secondo al quarto posto nella OWASP Top 10:2025, ma resta una categoria che causa danni gravi quando viene ignorata. La remediation copre due fronti: trasporto (TLS) e conservazione (hashing delle password). Per l’hashing, Argon2id è oggi la scelta raccomandata al posto di bcrypt o MD5.
// src/middleware/password.js
const argon2 = require('argon2');
async function hashPassword(plain) {
return argon2.hash(plain, {
type: argon2.argon2id,
memoryCost: 19456,
timeCost: 2,
parallelism: 1,
});
}
async function verifyPassword(hash, plain) {
return argon2.verify(hash, plain);
}
module.exports = { hashPassword, verifyPassword };
Sul lato trasporto, imposta il server dietro un reverse proxy con TLS 1.3 e disattiva esplicitamente i protocolli obsoleti. Non generare mai chiavi crittografiche con Math.random(): usa sempre il modulo crypto nativo di Node.js, che si appoggia al generatore di numeri casuali del sistema operativo.
I parametri memoryCost e timeCost nell’esempio sopra non sono arbitrari: bilanciano il tempo di verifica di un login (che deve restare rapido per l’utente) con il costo di un attacco a forza bruta offline. Se il tuo server ha vincoli di memoria stretti, riduci memoryCost gradualmente e misura il tempo di hashing reale: l’obiettivo pratico è restare sotto qualche centinaio di millisecondi per singola verifica, anche sotto carico.
Passo 6 – A05 Injection: query parametrizzate e validazione input
Injection scende dal terzo al quinto posto, ma resta una delle vulnerabilità più facili da sfruttare quando manca la parametrizzazione delle query. La regola non cambia da anni: mai concatenare input utente dentro una stringa SQL.
// Vulnerabile: concatenazione diretta
const query = `SELECT * FROM users WHERE email = '${email}'`;
// Corretto: query parametrizzata con pg
const { rows } = await pool.query(
'SELECT id, email, role FROM users WHERE email = $1',
[email]
);
Aggiungi anche uno strato di validazione dell’input in ingresso, prima ancora che raggiunga il database: controlla tipo, lunghezza e formato di ogni campo con una libreria di schema validation, e rifiuta la richiesta con un errore 400 se non rispetta lo schema atteso.
La stessa logica vale oltre SQL: comandi di sistema, query NoSQL e template engine lato server sono tutti bersagli della categoria A05 quando ricevono input non validato. Se il tuo progetto costruisce comandi shell a partire da dati utente, sostituisci sempre la concatenazione di stringhe con l’esecuzione tramite array di argomenti, che evita l’interpretazione di caratteri speciali da parte della shell.
Passo 7 – A06 Insecure Design e A08 Integrity Failures
Insecure Design scende dal quarto al sesto posto, ma è tra le categorie più difficili da correggere dopo il rilascio perché riguarda scelte architetturali, non singole righe di codice. La remediation qui è un threat modeling rapido: per ogni nuova funzionalità, chiediti chi può abusarne, cosa succede se un input arriva malformato e quale dato sensibile è esposto in caso di errore.
A08 Software or Data Integrity Failures riguarda invece la fiducia cieca in aggiornamenti, plugin o pacchetti senza verificarne l’integrità. La remediation minima è verificare firme e checksum prima di installare qualsiasi dipendenza in un ambiente di produzione.
Per il threat modeling di A06 non serve un processo pesante: bastano tre domande scritte in un documento condiviso per ogni nuova feature. Chi potrebbe voler abusare di questa funzionalità? Cosa succede se i dati arrivano vuoti, duplicati o fuori ordine? Quale informazione sensibile finirebbe esposta se questa parte del sistema fallisse? Le risposte, anche approssimative, guidano decisioni di design molto più solide di un controllo di sicurezza aggiunto a posteriori.
# Verifica dell'integrità del lockfile prima del deploy
npm ci --ignore-scripts
# Confronto dell'hash SHA-256 di un pacchetto scaricato
sha256sum trivy_0.71.0_Linux-64bit.tar.gz
# confronta con il valore pubblicato nella release ufficiale
Passo 8 – A07 Authentication Failures: MFA e sessioni sicure
Authentication Failures copre login deboli, password riutilizzate, sessioni che non scadono mai e flussi di autenticazione a due fattori che possono essere disattivati senza controlli sufficienti, esattamente come in CVE-2025-8850. La remediation pratica combina rate limiting sul login e una verifica esplicita del secondo fattore prima di qualsiasi operazione sensibile.
// src/middleware/rateLimit.js
const rateLimit = require('express-rate-limit');
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
message: { error: 'Troppi tentativi di accesso, riprova tra 15 minuti' },
standardHeaders: true,
legacyHeaders: false,
});
module.exports = { loginLimiter };
Applica loginLimiter solo alla route di login e a quella di verifica del codice MFA, non a tutta l’API: un rate limit troppo aggressivo su endpoint generici crea un problema di disponibilità che poi finisce nella categoria A10.
Oltre al rate limiting, imposta una scadenza esplicita per ogni sessione e invalida tutte le sessioni attive quando l’utente cambia password o disattiva la MFA. È lo stesso principio che manca in CVE-2025-8850: un flusso che modifica lo stato di sicurezza dell’account deve sempre richiedere una nuova verifica dell’identità, non solo un token di sessione ancora valido da prima della modifica.
Passo 9 – A09 e A10: logging, alerting e gestione degli errori
Security Logging & Alerting Failures (A09) e Mishandling of Exceptional Conditions (A10) sono strettamente collegate: la seconda è la categoria interamente nuova della edizione 2025 e riguarda errori gestiti male, condizioni limite ignorate e casi “fail open” dove un errore finisce per concedere accesso invece di negarlo. La remediation comune è un error handler centralizzato che logga tutto internamente ma non espone dettagli all’utente.
// src/middleware/errorHandler.js
const pino = require('pino')();
function errorHandler(err, req, res, next) {
pino.error({
err: err.message,
stack: err.stack,
path: req.path,
method: req.method,
userId: req.user ? req.user.id : null,
});
// Fail closed: in caso di dubbio, nega l'accesso
const status = err.status || 500;
res.status(status).json({
error: status === 500 ? 'Errore interno del server' : err.message,
});
}
module.exports = { errorHandler };
Nota due dettagli nel codice sopra: lo stack trace completo finisce nei log interni, mai nella risposta HTTP, e in caso di errore generico il sistema nega l’accesso invece di concederlo per default. Questo secondo punto è esattamente la differenza tra “fail open” e “fail closed” richiamata da A10.
Collega l’output di pino a un sistema centralizzato di raccolta log, anche una soluzione open source minimale, invece di lasciarlo solo su file locali nel server. Un log che nessuno consulta finché non serve non è remediation di A09, è solo un file che occupa spazio su disco: la parte di alerting, con soglie che notificano il team quando gli errori 500 superano un certo tasso in un intervallo di tempo, è quella che trasforma il logging in un vero strumento di incident response.
Passo 10 – Validare tutto con test automatici e pipeline CI/CD
L’ultimo passo trasforma la remediation manuale in un controllo automatico che gira a ogni commit. Aggiungi uno step di sicurezza alla pipeline CI/CD, così nessuna regressione arriva in produzione senza essere segnalata.
# .github/workflows/security.yml
name: security-checks
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24.18.1'
- run: npm ci
- run: npm audit --omit=dev --audit-level=high
- run: npx eslint src/
- name: Trivy filesystem scan
run: trivy fs --exit-code 1 --severity CRITICAL,HIGH .
Output atteso
Quando la pipeline gira senza vulnerabilità critiche, l’output di Trivy dovrebbe assomigliare a questo:
owasp-remediation-lab (node-pkg)
=================================
Total: 0 (CRITICAL: 0, HIGH: 0)
Suite: security-checks
OK npm audit: 0 vulnerabilita high o critical
OK eslint: nessun errore bloccante
OK trivy fs: nessun problema critico rilevato
Se invece la pipeline fallisce, non ignorare l’errore per sbloccare il merge: è il momento in cui la remediation funziona davvero, prima che il codice arrivi in produzione.
Strumenti per automatizzare la remediation OWASP
Nessun team applica manualmente tutti e dieci i passi ad ogni commit: la remediation diventa sostenibile solo quando è automatizzata dentro strumenti di scansione statica, dinamica e delle dipendenze. Ogni categoria della Top 10 ha una famiglia di tool più adatta a rilevarla, e sapere quale usare dove evita di comprare licenze ridondanti o, peggio, di lasciare scoperta una categoria intera.
| Tipo di scansione | Categorie OWASP coperte | Quando eseguirla |
|---|---|---|
| SAST (analisi statica del codice) | A05 Injection, A06 Insecure Design | Ad ogni pull request, prima del merge |
| DAST (analisi dinamica su app in esecuzione) | A01 Broken Access Control, A02 Security Misconfiguration | Su ambiente di staging, prima del deploy |
| SCA (analisi delle dipendenze, es. Trivy) | A03 Supply Chain Failures, A08 Integrity Failures | Ad ogni commit e su base pianificata giornaliera |
| Secrets scanning | A02 Security Misconfiguration, A04 Cryptographic Failures | Ad ogni push, prima che il commit raggiunga il branch condiviso |
Non serve adottare tutti e quattro i tipi di scansione lo stesso mese. Se il team è piccolo, parti da SCA e secrets scanning: sono i più economici da attivare, richiedono poca configurazione e coprono due categorie salite molto in classifica nella OWASP Top 10 2025, A02 e A03. SAST e DAST hanno una curva di adozione più lunga perché generano più falsi positivi all’inizio, ma diventano indispensabili man mano che l’applicazione cresce e il codice passa per più mani diverse.
Tabella riassuntiva: le 10 categorie e le azioni di remediation
| Categoria 2025 | Posizione 2021 | Posizione 2025 | Azione di remediation principale |
|---|---|---|---|
| A01 Broken Access Control | 1 | 1 | Middleware di autorizzazione per oggetto e ruolo, include SSRF |
| A02 Security Misconfiguration | 5 | 2 | Helmet, disabilitare debug e header verbosi |
| A03 Software Supply Chain Failures | Nuova | 3 | SBOM, npm audit, pin delle versioni dei tool |
| A04 Cryptographic Failures | 2 | 4 | TLS 1.3, Argon2id per l’hashing |
| A05 Injection | 3 | 5 | Query parametrizzate, validazione input |
| A06 Insecure Design | 4 | 6 | Threat modeling rapido per ogni feature |
| A07 Authentication Failures | 7 | 7 | Rate limiting sul login, MFA verificato lato server |
| A08 Software or Data Integrity Failures | 8 | 8 | Verifica firme e checksum dei pacchetti |
| A09 Security Logging & Alerting Failures | 9 | 9 | Error handler centralizzato, log senza dati sensibili |
| A10 Mishandling of Exceptional Conditions | Nuova | 10 | Fail closed sugli errori, gestione esplicita dei casi limite |
Errori comuni da evitare nella remediation OWASP Top 10
Anche seguendo tutti i dieci passi di questa guida, alcuni errori ricorrono spesso nei team che affrontano la remediation per la prima volta. Sono quasi sempre errori di processo più che di codice, e per questo passano inosservati finché non causano un incidente o un audit fallito.
- Trattare la Top 10 come una checklist statica. Le categorie descrivono classi di rischio, non singoli bug: un middleware di autorizzazione copre decine di endpoint diversi, non uno solo.
- Aggiungere Helmet senza configurare la CSP. I valori di default sono un buon punto di partenza, ma una Content Security Policy troppo permissiva vanifica gran parte del beneficio contro A02.
- Ignorare gli aggiornamenti dei tool di sicurezza stessi. L’incidente Trivy di marzo 2026 dimostra che anche gli strumenti di scansione possono diventare un vettore di attacco alla supply chain.
- Loggare troppo o troppo poco. Un log che include password o token in chiaro crea un nuovo problema di A09; un log troppo scarno rende impossibile l’incident response quando serve davvero.
- Rimandare la remediation di A06 Insecure Design a dopo il rilascio. Le scelte architetturali sono le più costose da correggere retroattivamente: vanno discusse prima di scrivere codice, non dopo.
- Applicare rate limiting solo sul login e dimenticare gli endpoint di reset password. Sono spesso il bersaglio più semplice per un attacco di enumerazione utenti.
Nessuno di questi errori richiede uno strumento nuovo per essere evitato: bastano una revisione del codice più attenta e una checklist condivisa da consultare prima di ogni rilascio, come quella riassunta nella tabella di questa guida.
Risoluzione dei problemi comuni (troubleshooting)
Durante l’applicazione dei dieci passi capita di incontrare errori che non dipendono dalla logica di remediation in sé, ma dall’integrazione con l’ambiente esistente. Ecco le situazioni più frequenti segnalate da chi ha già seguito questo tipo di percorso, con la causa più probabile e la soluzione diretta.
- Helmet blocca il caricamento di script esterni necessari. Aggiungi il dominio specifico a
scriptSrcnella Content Security Policy invece di disattivarla del tutto. - npm audit segnala vulnerabilità in una dipendenza transitiva senza fix disponibile. Usa
npm ls nome-pacchettoper capire chi la richiede e valuta un override temporaneo tramite il campooverridesinpackage.json. - argon2 fallisce l’installazione su alcuni ambienti CI. Il pacchetto compila un binding nativo: verifica che l’immagine CI includa i build tools richiesti oppure usa l’immagine ufficiale Node già pronta.
- Il rate limiter blocca utenti legittimi dietro lo stesso IP aziendale (NAT). Passa a una chiave combinata IP più identificativo utente invece del solo indirizzo IP.
- Trivy restituisce falsi positivi su pacchetti già corretti a runtime. Aggiorna il database delle vulnerabilità con
trivy image --download-db-onlyprima di ogni scansione programmata. - Le sessioni scadono troppo in fretta dopo l’attivazione di HSTS. HSTS riguarda solo il trasporto: se le sessioni scadono, controlla la configurazione del cookie di sessione, non l’header di sicurezza.
- La pipeline CI fallisce solo in produzione, non in locale. Controlla che le variabili d’ambiente richieste dal middleware di sicurezza siano definite anche nei secret della pipeline, non solo nel file
.envlocale. - Il threat model per A06 non converge mai su una decisione. Fissa un timebox di 30-45 minuti per sessione e documenta le decisioni prese anche se parziali: un threat model incompleto ma scritto vale più di uno perfetto mai concluso.
Consigli avanzati per team DevSecOps
Una volta completata la remediation di base, alcuni accorgimenti aggiuntivi alzano ulteriormente il livello di sicurezza senza stravolgere il workflow del team. Integra la scansione SBOM direttamente nel merge request, non solo nella pipeline notturna: un blocco immediato su una dipendenza critica costa molto meno di una scoperta a distanza di settimane. Ruota le chiavi API e i secret con una cadenza fissa, anche in assenza di un incidente noto, e automatizza la rotazione dove possibile invece di affidarti a un promemoria manuale.
Per team più maturi, vale la pena mappare esplicitamente ogni categoria della OWASP Top 10 2025 sui controlli richiesti dalla direttiva NIS2, così un singolo intervento di remediation copre due esigenze insieme: sicurezza tecnica e conformità normativa. Infine, tieni traccia delle metriche di remediation nel tempo, come il numero di vulnerabilità high o critical aperte per categoria: è un indicatore molto più utile del solo conteggio totale delle vulnerabilità.
Un ultimo consiglio riguarda la formazione del team: la remediation tecnica dura poco se chi scrive codice nuovo ogni giorno non capisce perché un certo pattern è vietato. Dedica una sessione breve, anche di 30 minuti al mese, a rivedere insieme un caso reale come CVE-2025-8850 o l’incidente Trivy di marzo 2026, invece di limitarti a distribuire un documento di policy che nessuno rilegge dopo la prima settimana.
NIS2, ENISA e conformità europea
Per le aziende italiane ed europee la remediation OWASP non è solo una questione tecnica. La direttiva NIS2 richiede alle entità essenziali e importanti di dimostrare misure di sicurezza allineate allo stato dell’arte, e diversi fornitori di sicurezza citano proprio la OWASP Top 10:2025 come base tecnica di riferimento per questo requisito. ENISA, l’agenzia europea per la cybersicurezza, pubblica linee guida complementari che si sovrappongono in larga parte alle stesse dieci categorie.
Nella pratica, un audit NIS2 non chiede di citare letteralmente “OWASP Top 10” in un documento, ma di dimostrare un processo di gestione del rischio applicativo continuo e documentato. Il SBOM generato al passo 4, i log strutturati del passo 9 e la pipeline CI del passo 10 diventano evidenze concrete da mostrare durante un audit, molto più convincenti di una policy scritta ma mai applicata nei repository reali.
| Ambito di conformità | Riferimento | Collegamento con la OWASP Top 10 2025 |
|---|---|---|
| Direttiva NIS2 | Entità essenziali e importanti UE | Base tecnica per dimostrare misure allo stato dell’arte |
| Linee guida ENISA | Agenzia europea cybersicurezza | Copertura complementare su gestione del rischio |
| Cyber Resilience Act | Prodotti con elementi digitali | Richiede SBOM e gestione vulnerabilità, in linea con A03 |
Per un team italiano che vende software con componenti digitali in Europa, il Cyber Resilience Act aggiunge un obbligo diretto di gestione delle vulnerabilità lungo tutto il ciclo di vita del prodotto, non solo al momento del rilascio iniziale. Il SBOM generato al passo 4 e la pipeline di scansione del passo 10 non sono quindi solo buone pratiche tecniche: diventano la base documentale su cui costruire la conformità richiesta dal regolamento, con il vantaggio di essere già automatizzate invece di dipendere da un controllo manuale periodico.
Domande frequenti
Quanto tempo serve per applicare la remediation completa della OWASP Top 10:2025?
Per un’applicazione media, seguendo i dieci passi di questa guida, il lavoro tecnico richiede tra le 8 e le 16 ore, distribuite su più giorni per lasciare spazio ai test. La parte più lunga di solito è il threat modeling di A06, non la scrittura del codice. Su un’applicazione legacy di grandi dimensioni, con molte route non documentate, il tempo può salire di parecchio: in quel caso conviene affrontare prima A01 e A02, che coprono la superficie di attacco più ampia con il minor sforzo iniziale.
La OWASP Top 10 2025 sostituisce completamente quella del 2021?
Sì, OWASP la presenta come la versione corrente e di riferimento. La versione 2021 resta consultabile per motivi storici, ma i nuovi progetti dovrebbero partire direttamente dalla struttura A01-A10 del 2025.
Devo usare per forza Node.js ed Express per applicare questa guida?
No. Gli esempi di codice usano Node.js perché è uno stack comune, ma ogni categoria ha equivalenti diretti in altri linguaggi: Spring Security per Java su A01, Django ORM per la parametrizzazione delle query su A05, e così via.
Perché Security Misconfiguration è salita così tanto in classifica?
Perché l’adozione di cloud, container e pipeline CI/CD ha moltiplicato i punti in cui una configurazione può essere lasciata troppo permissiva, mentre le classi di vulnerabilità più “classiche” come injection sono oggi meglio comprese e più spesso intercettate da strumenti automatici.
Cos’è esattamente un SBOM e perché serve per A03?
Un SBOM (Software Bill of Materials) è un elenco strutturato di tutte le dipendenze usate da un’applicazione, comprese quelle indirette. Serve a sapere, in caso di una nuova vulnerabilità pubblicata, se e dove il progetto è esposto senza dover controllare manualmente ogni pacchetto. I due formati più diffusi sono CycloneDX e SPDX: entrambi vanno bene per iniziare, la scelta conta meno rispetto al fatto di generarlo e conservarlo davvero ad ogni release.
argon2 è davvero meglio di bcrypt per l’hashing delle password?
Argon2id è il vincitore della Password Hashing Competition ed è oggi la raccomandazione di riferimento per nuovi progetti. bcrypt resta accettabile su sistemi legacy, ma per un nuovo sviluppo conviene partire direttamente da argon2id.
Come si collega A10 Mishandling of Exceptional Conditions all’incident response?
Una gestione degli errori che segue il principio “fail closed” riduce il numero di incidenti che arrivano fino al SOC, perché molte condizioni anomale vengono bloccate automaticamente invece di essere silenziosamente concesse.
Serve rifare tutta la remediation a ogni nuova edizione della OWASP Top 10?
No, ma conviene rivedere il mapping tra categorie vecchie e nuove, come nella tabella di questa guida, e verificare se i controlli esistenti coprono ancora le categorie che hanno cambiato definizione, in particolare A03 e A10.
Related Coverage
- OWASP Top 10 2025 vs API Security Top 10: 10 vs 10
- SBOM e Dependency Scan in Node.js: 12 Step, 40 Min
- CISA KEV: 16 Falle in 3 Settimane, 4 Critiche
- Wiz vs Orca Security: Minuti vs 24 Ore di Scansione
- SMS vs App vs Passkey vs Chiave Hardware: 5 Miliardi Attive
Per altri approfondimenti sulla sicurezza applicativa, consulta la sezione Sicurezza di shattered.io.
La OWASP Top 10:2025 ha cambiato le priorità con cui ogni team di sviluppo deve mettere in sicurezza un’applicazione web. Non è un semplice aggiornamento cosmetico della lista del 2021: due categorie sono completamente nuove, una risale dal quinto al secondo posto e la SSRF è stata assorbita in un’altra voce. Questa guida mostra, passo dopo passo, come costruire un piccolo progetto Node.js e applicare la remediation a ciascuna delle dieci categorie, con codice reale da copiare, incollare e adattare. Alla fine avrai un’applicazione di riferimento già indurita secondo la OWASP Top 10 2025 e una checklist da riusare su qualsiasi progetto.
Il tutorial è pensato per chi lavora già su codice in produzione e non ha tempo di leggere l’intero documento OWASP prima di agire. Ogni passo parte da una domanda concreta: cosa cambia rispetto al 2021, quale codice risolve il problema e come verifico che il fix funzioni davvero. Se sei un developer, un tech lead o parte di un team di sicurezza applicativa in Italia, alla fine di questa guida avrai sia il codice sia il ragionamento dietro ogni scelta, utile anche per motivare la priorità di un intervento davanti a un product owner o un auditor NIS2.
Cos’è la OWASP Top 10:2025 e perché cambia le priorità
OWASP ha pubblicato la nuova edizione della Top 10 alla fine del 2025, sostituendo la lista del 2021 dopo un’analisi di milioni di test automatizzati su applicazioni reali. La struttura resta la stessa, dieci categorie da A01 a A10, ma l’ordine e i contenuti cambiano in modo sostanziale. Il documento ufficiale è disponibile anche in traduzione italiana, un dettaglio utile per i team che devono presentare la remediation a manager e auditor non tecnici.
La OWASP Top 10 resta il riferimento più citato per la sicurezza delle applicazioni web, ma la versione 2025 sposta l’attenzione dal singolo bug al processo che lo genera. Due categorie sono del tutto nuove: A03 Software Supply Chain Failures e A10 Mishandling of Exceptional Conditions. La SSRF, prima voce a sé, è confluita dentro A01 Broken Access Control insieme a BOLA e BFLA.
La metodologia con cui OWASP costruisce la classifica non è cambiata: il progetto raccoglie dati da scanner automatici, bug bounty e survey tra practitioner, poi normalizza i risultati in categorie ampie invece di elencare CWE singole. Questo spiega perché una categoria come A03 Software Supply Chain Failures possa comparire in posizione alta anche con un numero relativamente basso di occorrenze nei test: il punteggio tiene conto anche della gravità media dell’impatto, non solo della frequenza. Per chi fa remediation, la conseguenza pratica è che alcune categorie meritano priorità anche quando sembrano meno “visibili” nei log quotidiani.
Cosa cambia rispetto alla OWASP Top 10:2021
Broken Access Control resta al primo posto, ma tre categorie cambiano ordine in modo netto. Security Misconfiguration passa dal quinto al secondo posto. Cryptographic Failures scende dal secondo al quarto. Injection scivola dal terzo al quinto e Insecure Design dal quarto al sesto. Il messaggio per chi fa remediation è chiaro: le configurazioni sbagliate in cloud, container e pipeline CI/CD oggi pesano più degli errori di crittografia o delle classiche injection, anche se restano tutte da correggere.
Prerequisiti: strumenti e versioni per seguire il tutorial
Prima di iniziare la remediation servono alcuni strumenti installati e funzionanti. Il tutorial usa Node.js e Express come base dimostrativa perché è lo stack più comune tra i lettori italiani che lavorano su API e backend, ma i principi si applicano a Java, Python o PHP con librerie equivalenti.
- Node.js 24.18.1 (ramo LTS attuale) o versione LTS successiva
- npm incluso nell’installazione di Node.js, usato per l’audit delle dipendenze
- Express 4.x come framework HTTP di esempio
- Helmet 8.3.0 per gli header di sicurezza
- argon2 0.45.1 per l’hashing delle password
- Trivy v0.71.0 per la scansione di immagini e SBOM (verifica sempre la firma del binario prima di installarlo)
- Un editor di codice e un terminale con accesso a git
- Un database PostgreSQL o SQLite locale per gli esempi di query
Verifica ogni installazione con il relativo comando --version prima di procedere: una versione di Node.js troppo vecchia può far fallire silenziosamente l’installazione di argon2, che compila un binding nativo in fase di npm install. Se lavori in team, annota le versioni scelte in un file .nvmrc o equivalente, così ogni sviluppatore parte dallo stesso ambiente e i problemi di compatibilità non si manifestano solo in CI.
Non serve un cluster Kubernetes né un ambiente cloud per seguire la guida: tutto gira in locale su una singola macchina, in modo da isolare la logica di remediation dal rumore dell’infrastruttura.
Se il tuo progetto reale usa un linguaggio diverso da Node.js, mantieni comunque la stessa sequenza di passi: cambia solo la libreria da installare per ogni categoria. In Java lo strato di autorizzazione arriva tipicamente da Spring Security, in Python da un middleware Django o FastAPI dependency, in PHP da un pacchetto come Symfony Security. I nomi cambiano, ma il ragionamento dietro ogni fix resta identico da uno stack all’altro, ed è proprio questo ragionamento l’obiettivo principale della guida.
Passo 1 – Creare il progetto demo da mettere in sicurezza
Il primo passo crea uno scheletro di API volutamente permissivo, che useremo come base per applicare ogni fix. Apri il terminale e lancia questi comandi.
mkdir owasp-remediation-lab && cd owasp-remediation-lab
npm init -y
npm install express helmet argon2 dotenv pg express-rate-limit pino
npm install --save-dev eslint
Struttura del progetto
Organizza le cartelle così, separando configurazione, middleware e route fin dall’inizio: mescolare tutto in un unico file rende la remediation molto più lenta man mano che il progetto cresce.
owasp-remediation-lab/
src/
config/
middleware/
routes/
server.js
.env
package.json
Con la struttura pronta, i prossimi dieci passi affrontano una categoria della OWASP Top 10 2025 alla volta, dalla più critica alla meno urgente secondo il nuovo ordinamento.
Passo 2 – A01 Broken Access Control: middleware di autorizzazione
Broken Access Control resta la categoria numero uno e ora include esplicitamente SSRF, BOLA (Broken Object Level Authorization) e BFLA (Broken Function Level Authorization). La remediation pratica parte da un middleware che verifica proprietà e ruolo su ogni oggetto, non solo l’autenticazione dell’utente.
// src/middleware/authorize.js
function authorize(requiredRole) {
return (req, res, next) => {
const user = req.user;
if (!user) {
return res.status(401).json({ error: 'Autenticazione richiesta' });
}
if (user.role !== requiredRole && user.role !== 'admin') {
return res.status(403).json({ error: 'Accesso negato' });
}
next();
};
}
function ownsResource(getOwnerId) {
return async (req, res, next) => {
const ownerId = await getOwnerId(req.params.id);
if (ownerId !== req.user.id && req.user.role !== 'admin') {
return res.status(403).json({ error: 'Risorsa non tua' });
}
next();
};
}
module.exports = { authorize, ownsResource };
Il caso reale da conoscere qui è CVE-2025-8850, un difetto di design nell’API di LibreChat 0.7.9 che permetteva di disattivare la verifica a due fattori senza i controlli di autorizzazione corretti. È l’esempio perfetto di come A01 e A07 finiscano per intrecciarsi: un endpoint di gestione account senza controllo di ownership diventa un modo per bypassare il secondo fattore.
Nota che ownsResource richiede una funzione asincrona che recuperi il proprietario reale della risorsa dal database, non un valore già presente nella richiesta. Fidarsi di un ownerId passato dal client nel body o nella query string riapre esattamente lo stesso buco che il middleware dovrebbe chiudere: l’unica fonte affidabile è sempre il record salvato lato server. Applica questo middleware su ogni route che espone o modifica un oggetto identificato da ID, comprese quelle interne usate solo dal pannello di amministrazione.
Passo 3 – A02 Security Misconfiguration: hardening con Helmet
Security Misconfiguration è la categoria che è salita di più nella nuova classifica, dal quinto al secondo posto. Riguarda porte di debug lasciate aperte, messaggi di errore troppo verbosi, permessi cloud troppo larghi e header HTTP mancanti. La remediation più rapida per un’app Express è Helmet, che imposta un set di header sicuri con poche righe.
// src/server.js
const express = require('express');
const helmet = require('helmet');
require('dotenv').config();
const app = express();
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
objectSrc: ["'none'"],
},
},
hsts: { maxAge: 63072000, includeSubDomains: true, preload: true },
}));
app.disable('x-powered-by');
app.set('trust proxy', 1);
if (process.env.NODE_ENV === 'production') {
app.use((req, res, next) => {
if (!req.secure) return res.redirect(`https://${req.headers.host}${req.url}`);
next();
});
}
Verifica l’effetto con una chiamata curl prima e dopo l’attivazione di Helmet: la differenza negli header di risposta è immediata.
$ curl -I http://localhost:3000/
# Prima di Helmet
HTTP/1.1 200 OK
X-Powered-By: Express
# Dopo Helmet
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'
Un altro punto della remediation A02 riguarda i segreti: nessuna chiave API o password deve stare nel codice sorgente. Usa sempre variabili d’ambiente caricate da un file .env escluso da git tramite .gitignore.
Ricorda anche di disattivare i messaggi di stack trace dettagliati quando NODE_ENV è impostato su production: molti framework, incluso Express, mostrano per default informazioni interne utili in sviluppo ma pericolose se esposte a un utente reale. Un errore 500 in produzione deve restituire un messaggio generico, mentre il dettaglio completo resta solo nei log interni, gestiti al passo 9 di questa guida.
Passo 4 – A03 Software Supply Chain Failures: SBOM e npm audit
A03 è una delle due categorie completamente nuove della OWASP Top 10 2025. Amplia la vecchia “Vulnerable and Outdated Components” per coprire l’intera catena: dipendenze, sistemi di build, pipeline CI/CD e distribuzione del pacchetto finale. Il primo passo di remediation è generare un SBOM (Software Bill of Materials) e integrarlo nella pipeline.
# Audit rapido delle dipendenze npm
npm audit --omit=dev
# Generazione di un SBOM in formato CycloneDX con Trivy
trivy fs --format cyclonedx --output sbom.json .
# Scansione delle vulnerabilità note sul SBOM appena generato
trivy sbom sbom.json --severity CRITICAL,HIGH
Un esempio concreto del perché questa categoria pesa così tanto: nel marzo 2026 Trivy stesso è stato colpito da un attacco alla supply chain, con una release v0.69.4 compromessa e immagini Docker Hub corrispondenti anch’esse manomesse, come documentato da GitLab nella loro analisi della OWASP Top 10 2025. La lezione pratica è semplice: fissa (pin) le versioni dei tool di sicurezza, verifica gli hash dei binari scaricati e non aggiornare mai automaticamente in produzione senza controllo.
Un SBOM in formato CycloneDX o SPDX serve anche per un secondo motivo, oltre alla scansione: quando una nuova CVE viene pubblicata su una libreria diffusa, puoi rispondere in minuti alla domanda “siamo esposti?” facendo una ricerca sul file invece di controllare manualmente ogni progetto attivo in azienda. Conserva il SBOM generato ad ogni release insieme al tag di versione, così hai uno storico consultabile in caso di audit o di un incidente scoperto mesi dopo.
Passo 5 – A04 Cryptographic Failures: TLS e hashing con Argon2
Cryptographic Failures scende dal secondo al quarto posto nella OWASP Top 10:2025, ma resta una categoria che causa danni gravi quando viene ignorata. La remediation copre due fronti: trasporto (TLS) e conservazione (hashing delle password). Per l’hashing, Argon2id è oggi la scelta raccomandata al posto di bcrypt o MD5.
// src/middleware/password.js
const argon2 = require('argon2');
async function hashPassword(plain) {
return argon2.hash(plain, {
type: argon2.argon2id,
memoryCost: 19456,
timeCost: 2,
parallelism: 1,
});
}
async function verifyPassword(hash, plain) {
return argon2.verify(hash, plain);
}
module.exports = { hashPassword, verifyPassword };
Sul lato trasporto, imposta il server dietro un reverse proxy con TLS 1.3 e disattiva esplicitamente i protocolli obsoleti. Non generare mai chiavi crittografiche con Math.random(): usa sempre il modulo crypto nativo di Node.js, che si appoggia al generatore di numeri casuali del sistema operativo.
I parametri memoryCost e timeCost nell’esempio sopra non sono arbitrari: bilanciano il tempo di verifica di un login (che deve restare rapido per l’utente) con il costo di un attacco a forza bruta offline. Se il tuo server ha vincoli di memoria stretti, riduci memoryCost gradualmente e misura il tempo di hashing reale: l’obiettivo pratico è restare sotto qualche centinaio di millisecondi per singola verifica, anche sotto carico.
Passo 6 – A05 Injection: query parametrizzate e validazione input
Injection scende dal terzo al quinto posto, ma resta una delle vulnerabilità più facili da sfruttare quando manca la parametrizzazione delle query. La regola non cambia da anni: mai concatenare input utente dentro una stringa SQL.
// Vulnerabile: concatenazione diretta
const query = `SELECT * FROM users WHERE email = '${email}'`;
// Corretto: query parametrizzata con pg
const { rows } = await pool.query(
'SELECT id, email, role FROM users WHERE email = $1',
[email]
);
Aggiungi anche uno strato di validazione dell’input in ingresso, prima ancora che raggiunga il database: controlla tipo, lunghezza e formato di ogni campo con una libreria di schema validation, e rifiuta la richiesta con un errore 400 se non rispetta lo schema atteso.
La stessa logica vale oltre SQL: comandi di sistema, query NoSQL e template engine lato server sono tutti bersagli della categoria A05 quando ricevono input non validato. Se il tuo progetto costruisce comandi shell a partire da dati utente, sostituisci sempre la concatenazione di stringhe con l’esecuzione tramite array di argomenti, che evita l’interpretazione di caratteri speciali da parte della shell.
Passo 7 – A06 Insecure Design e A08 Integrity Failures
Insecure Design scende dal quarto al sesto posto, ma è tra le categorie più difficili da correggere dopo il rilascio perché riguarda scelte architetturali, non singole righe di codice. La remediation qui è un threat modeling rapido: per ogni nuova funzionalità, chiediti chi può abusarne, cosa succede se un input arriva malformato e quale dato sensibile è esposto in caso di errore.
A08 Software or Data Integrity Failures riguarda invece la fiducia cieca in aggiornamenti, plugin o pacchetti senza verificarne l’integrità. La remediation minima è verificare firme e checksum prima di installare qualsiasi dipendenza in un ambiente di produzione.
Per il threat modeling di A06 non serve un processo pesante: bastano tre domande scritte in un documento condiviso per ogni nuova feature. Chi potrebbe voler abusare di questa funzionalità? Cosa succede se i dati arrivano vuoti, duplicati o fuori ordine? Quale informazione sensibile finirebbe esposta se questa parte del sistema fallisse? Le risposte, anche approssimative, guidano decisioni di design molto più solide di un controllo di sicurezza aggiunto a posteriori.
# Verifica dell'integrità del lockfile prima del deploy
npm ci --ignore-scripts
# Confronto dell'hash SHA-256 di un pacchetto scaricato
sha256sum trivy_0.71.0_Linux-64bit.tar.gz
# confronta con il valore pubblicato nella release ufficiale
Passo 8 – A07 Authentication Failures: MFA e sessioni sicure
Authentication Failures copre login deboli, password riutilizzate, sessioni che non scadono mai e flussi di autenticazione a due fattori che possono essere disattivati senza controlli sufficienti, esattamente come in CVE-2025-8850. La remediation pratica combina rate limiting sul login e una verifica esplicita del secondo fattore prima di qualsiasi operazione sensibile.
// src/middleware/rateLimit.js
const rateLimit = require('express-rate-limit');
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
message: { error: 'Troppi tentativi di accesso, riprova tra 15 minuti' },
standardHeaders: true,
legacyHeaders: false,
});
module.exports = { loginLimiter };
Applica loginLimiter solo alla route di login e a quella di verifica del codice MFA, non a tutta l’API: un rate limit troppo aggressivo su endpoint generici crea un problema di disponibilità che poi finisce nella categoria A10.
Oltre al rate limiting, imposta una scadenza esplicita per ogni sessione e invalida tutte le sessioni attive quando l’utente cambia password o disattiva la MFA. È lo stesso principio che manca in CVE-2025-8850: un flusso che modifica lo stato di sicurezza dell’account deve sempre richiedere una nuova verifica dell’identità, non solo un token di sessione ancora valido da prima della modifica.
Passo 9 – A09 e A10: logging, alerting e gestione degli errori
Security Logging & Alerting Failures (A09) e Mishandling of Exceptional Conditions (A10) sono strettamente collegate: la seconda è la categoria interamente nuova della edizione 2025 e riguarda errori gestiti male, condizioni limite ignorate e casi “fail open” dove un errore finisce per concedere accesso invece di negarlo. La remediation comune è un error handler centralizzato che logga tutto internamente ma non espone dettagli all’utente.
// src/middleware/errorHandler.js
const pino = require('pino')();
function errorHandler(err, req, res, next) {
pino.error({
err: err.message,
stack: err.stack,
path: req.path,
method: req.method,
userId: req.user ? req.user.id : null,
});
// Fail closed: in caso di dubbio, nega l'accesso
const status = err.status || 500;
res.status(status).json({
error: status === 500 ? 'Errore interno del server' : err.message,
});
}
module.exports = { errorHandler };
Nota due dettagli nel codice sopra: lo stack trace completo finisce nei log interni, mai nella risposta HTTP, e in caso di errore generico il sistema nega l’accesso invece di concederlo per default. Questo secondo punto è esattamente la differenza tra “fail open” e “fail closed” richiamata da A10.
Collega l’output di pino a un sistema centralizzato di raccolta log, anche una soluzione open source minimale, invece di lasciarlo solo su file locali nel server. Un log che nessuno consulta finché non serve non è remediation di A09, è solo un file che occupa spazio su disco: la parte di alerting, con soglie che notificano il team quando gli errori 500 superano un certo tasso in un intervallo di tempo, è quella che trasforma il logging in un vero strumento di incident response.
Passo 10 – Validare tutto con test automatici e pipeline CI/CD
L’ultimo passo trasforma la remediation manuale in un controllo automatico che gira a ogni commit. Aggiungi uno step di sicurezza alla pipeline CI/CD, così nessuna regressione arriva in produzione senza essere segnalata.
# .github/workflows/security.yml
name: security-checks
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24.18.1'
- run: npm ci
- run: npm audit --omit=dev --audit-level=high
- run: npx eslint src/
- name: Trivy filesystem scan
run: trivy fs --exit-code 1 --severity CRITICAL,HIGH .
Output atteso
Quando la pipeline gira senza vulnerabilità critiche, l’output di Trivy dovrebbe assomigliare a questo:
owasp-remediation-lab (node-pkg)
=================================
Total: 0 (CRITICAL: 0, HIGH: 0)
Suite: security-checks
OK npm audit: 0 vulnerabilita high o critical
OK eslint: nessun errore bloccante
OK trivy fs: nessun problema critico rilevato
Se invece la pipeline fallisce, non ignorare l’errore per sbloccare il merge: è il momento in cui la remediation funziona davvero, prima che il codice arrivi in produzione.
Strumenti per automatizzare la remediation OWASP
Nessun team applica manualmente tutti e dieci i passi ad ogni commit: la remediation diventa sostenibile solo quando è automatizzata dentro strumenti di scansione statica, dinamica e delle dipendenze. Ogni categoria della Top 10 ha una famiglia di tool più adatta a rilevarla, e sapere quale usare dove evita di comprare licenze ridondanti o, peggio, di lasciare scoperta una categoria intera.
| Tipo di scansione | Categorie OWASP coperte | Quando eseguirla |
|---|---|---|
| SAST (analisi statica del codice) | A05 Injection, A06 Insecure Design | Ad ogni pull request, prima del merge |
| DAST (analisi dinamica su app in esecuzione) | A01 Broken Access Control, A02 Security Misconfiguration | Su ambiente di staging, prima del deploy |
| SCA (analisi delle dipendenze, es. Trivy) | A03 Supply Chain Failures, A08 Integrity Failures | Ad ogni commit e su base pianificata giornaliera |
| Secrets scanning | A02 Security Misconfiguration, A04 Cryptographic Failures | Ad ogni push, prima che il commit raggiunga il branch condiviso |
Non serve adottare tutti e quattro i tipi di scansione lo stesso mese. Se il team è piccolo, parti da SCA e secrets scanning: sono i più economici da attivare, richiedono poca configurazione e coprono due categorie salite molto in classifica nella OWASP Top 10 2025, A02 e A03. SAST e DAST hanno una curva di adozione più lunga perché generano più falsi positivi all’inizio, ma diventano indispensabili man mano che l’applicazione cresce e il codice passa per più mani diverse.
Tabella riassuntiva: le 10 categorie e le azioni di remediation
| Categoria 2025 | Posizione 2021 | Posizione 2025 | Azione di remediation principale |
|---|---|---|---|
| A01 Broken Access Control | 1 | 1 | Middleware di autorizzazione per oggetto e ruolo, include SSRF |
| A02 Security Misconfiguration | 5 | 2 | Helmet, disabilitare debug e header verbosi |
| A03 Software Supply Chain Failures | Nuova | 3 | SBOM, npm audit, pin delle versioni dei tool |
| A04 Cryptographic Failures | 2 | 4 | TLS 1.3, Argon2id per l’hashing |
| A05 Injection | 3 | 5 | Query parametrizzate, validazione input |
| A06 Insecure Design | 4 | 6 | Threat modeling rapido per ogni feature |
| A07 Authentication Failures | 7 | 7 | Rate limiting sul login, MFA verificato lato server |
| A08 Software or Data Integrity Failures | 8 | 8 | Verifica firme e checksum dei pacchetti |
| A09 Security Logging & Alerting Failures | 9 | 9 | Error handler centralizzato, log senza dati sensibili |
| A10 Mishandling of Exceptional Conditions | Nuova | 10 | Fail closed sugli errori, gestione esplicita dei casi limite |
Errori comuni da evitare nella remediation OWASP Top 10
Anche seguendo tutti i dieci passi di questa guida, alcuni errori ricorrono spesso nei team che affrontano la remediation per la prima volta. Sono quasi sempre errori di processo più che di codice, e per questo passano inosservati finché non causano un incidente o un audit fallito.
- Trattare la Top 10 come una checklist statica. Le categorie descrivono classi di rischio, non singoli bug: un middleware di autorizzazione copre decine di endpoint diversi, non uno solo.
- Aggiungere Helmet senza configurare la CSP. I valori di default sono un buon punto di partenza, ma una Content Security Policy troppo permissiva vanifica gran parte del beneficio contro A02.
- Ignorare gli aggiornamenti dei tool di sicurezza stessi. L’incidente Trivy di marzo 2026 dimostra che anche gli strumenti di scansione possono diventare un vettore di attacco alla supply chain.
- Loggare troppo o troppo poco. Un log che include password o token in chiaro crea un nuovo problema di A09; un log troppo scarno rende impossibile l’incident response quando serve davvero.
- Rimandare la remediation di A06 Insecure Design a dopo il rilascio. Le scelte architetturali sono le più costose da correggere retroattivamente: vanno discusse prima di scrivere codice, non dopo.
- Applicare rate limiting solo sul login e dimenticare gli endpoint di reset password. Sono spesso il bersaglio più semplice per un attacco di enumerazione utenti.
Nessuno di questi errori richiede uno strumento nuovo per essere evitato: bastano una revisione del codice più attenta e una checklist condivisa da consultare prima di ogni rilascio, come quella riassunta nella tabella di questa guida.
Risoluzione dei problemi comuni (troubleshooting)
Durante l’applicazione dei dieci passi capita di incontrare errori che non dipendono dalla logica di remediation in sé, ma dall’integrazione con l’ambiente esistente. Ecco le situazioni più frequenti segnalate da chi ha già seguito questo tipo di percorso, con la causa più probabile e la soluzione diretta.
- Helmet blocca il caricamento di script esterni necessari. Aggiungi il dominio specifico a
scriptSrcnella Content Security Policy invece di disattivarla del tutto. - npm audit segnala vulnerabilità in una dipendenza transitiva senza fix disponibile. Usa
npm ls nome-pacchettoper capire chi la richiede e valuta un override temporaneo tramite il campooverridesinpackage.json. - argon2 fallisce l’installazione su alcuni ambienti CI. Il pacchetto compila un binding nativo: verifica che l’immagine CI includa i build tools richiesti oppure usa l’immagine ufficiale Node già pronta.
- Il rate limiter blocca utenti legittimi dietro lo stesso IP aziendale (NAT). Passa a una chiave combinata IP più identificativo utente invece del solo indirizzo IP.
- Trivy restituisce falsi positivi su pacchetti già corretti a runtime. Aggiorna il database delle vulnerabilità con
trivy image --download-db-onlyprima di ogni scansione programmata. - Le sessioni scadono troppo in fretta dopo l’attivazione di HSTS. HSTS riguarda solo il trasporto: se le sessioni scadono, controlla la configurazione del cookie di sessione, non l’header di sicurezza.
- La pipeline CI fallisce solo in produzione, non in locale. Controlla che le variabili d’ambiente richieste dal middleware di sicurezza siano definite anche nei secret della pipeline, non solo nel file
.envlocale. - Il threat model per A06 non converge mai su una decisione. Fissa un timebox di 30-45 minuti per sessione e documenta le decisioni prese anche se parziali: un threat model incompleto ma scritto vale più di uno perfetto mai concluso.
Consigli avanzati per team DevSecOps
Una volta completata la remediation di base, alcuni accorgimenti aggiuntivi alzano ulteriormente il livello di sicurezza senza stravolgere il workflow del team. Integra la scansione SBOM direttamente nel merge request, non solo nella pipeline notturna: un blocco immediato su una dipendenza critica costa molto meno di una scoperta a distanza di settimane. Ruota le chiavi API e i secret con una cadenza fissa, anche in assenza di un incidente noto, e automatizza la rotazione dove possibile invece di affidarti a un promemoria manuale.
Per team più maturi, vale la pena mappare esplicitamente ogni categoria della OWASP Top 10 2025 sui controlli richiesti dalla direttiva NIS2, così un singolo intervento di remediation copre due esigenze insieme: sicurezza tecnica e conformità normativa. Infine, tieni traccia delle metriche di remediation nel tempo, come il numero di vulnerabilità high o critical aperte per categoria: è un indicatore molto più utile del solo conteggio totale delle vulnerabilità.
Un ultimo consiglio riguarda la formazione del team: la remediation tecnica dura poco se chi scrive codice nuovo ogni giorno non capisce perché un certo pattern è vietato. Dedica una sessione breve, anche di 30 minuti al mese, a rivedere insieme un caso reale come CVE-2025-8850 o l’incidente Trivy di marzo 2026, invece di limitarti a distribuire un documento di policy che nessuno rilegge dopo la prima settimana.
NIS2, ENISA e conformità europea
Per le aziende italiane ed europee la remediation OWASP non è solo una questione tecnica. La direttiva NIS2 richiede alle entità essenziali e importanti di dimostrare misure di sicurezza allineate allo stato dell’arte, e diversi fornitori di sicurezza citano proprio la OWASP Top 10:2025 come base tecnica di riferimento per questo requisito. ENISA, l’agenzia europea per la cybersicurezza, pubblica linee guida complementari che si sovrappongono in larga parte alle stesse dieci categorie.
Nella pratica, un audit NIS2 non chiede di citare letteralmente “OWASP Top 10” in un documento, ma di dimostrare un processo di gestione del rischio applicativo continuo e documentato. Il SBOM generato al passo 4, i log strutturati del passo 9 e la pipeline CI del passo 10 diventano evidenze concrete da mostrare durante un audit, molto più convincenti di una policy scritta ma mai applicata nei repository reali.
| Ambito di conformità | Riferimento | Collegamento con la OWASP Top 10 2025 |
|---|---|---|
| Direttiva NIS2 | Entità essenziali e importanti UE | Base tecnica per dimostrare misure allo stato dell’arte |
| Linee guida ENISA | Agenzia europea cybersicurezza | Copertura complementare su gestione del rischio |
| Cyber Resilience Act | Prodotti con elementi digitali | Richiede SBOM e gestione vulnerabilità, in linea con A03 |
Per un team italiano che vende software con componenti digitali in Europa, il Cyber Resilience Act aggiunge un obbligo diretto di gestione delle vulnerabilità lungo tutto il ciclo di vita del prodotto, non solo al momento del rilascio iniziale. Il SBOM generato al passo 4 e la pipeline di scansione del passo 10 non sono quindi solo buone pratiche tecniche: diventano la base documentale su cui costruire la conformità richiesta dal regolamento, con il vantaggio di essere già automatizzate invece di dipendere da un controllo manuale periodico.
Domande frequenti
Quanto tempo serve per applicare la remediation completa della OWASP Top 10:2025?
Per un’applicazione media, seguendo i dieci passi di questa guida, il lavoro tecnico richiede tra le 8 e le 16 ore, distribuite su più giorni per lasciare spazio ai test. La parte più lunga di solito è il threat modeling di A06, non la scrittura del codice. Su un’applicazione legacy di grandi dimensioni, con molte route non documentate, il tempo può salire di parecchio: in quel caso conviene affrontare prima A01 e A02, che coprono la superficie di attacco più ampia con il minor sforzo iniziale.
La OWASP Top 10 2025 sostituisce completamente quella del 2021?
Sì, OWASP la presenta come la versione corrente e di riferimento. La versione 2021 resta consultabile per motivi storici, ma i nuovi progetti dovrebbero partire direttamente dalla struttura A01-A10 del 2025.
Devo usare per forza Node.js ed Express per applicare questa guida?
No. Gli esempi di codice usano Node.js perché è uno stack comune, ma ogni categoria ha equivalenti diretti in altri linguaggi: Spring Security per Java su A01, Django ORM per la parametrizzazione delle query su A05, e così via.
Perché Security Misconfiguration è salita così tanto in classifica?
Perché l’adozione di cloud, container e pipeline CI/CD ha moltiplicato i punti in cui una configurazione può essere lasciata troppo permissiva, mentre le classi di vulnerabilità più “classiche” come injection sono oggi meglio comprese e più spesso intercettate da strumenti automatici.
Cos’è esattamente un SBOM e perché serve per A03?
Un SBOM (Software Bill of Materials) è un elenco strutturato di tutte le dipendenze usate da un’applicazione, comprese quelle indirette. Serve a sapere, in caso di una nuova vulnerabilità pubblicata, se e dove il progetto è esposto senza dover controllare manualmente ogni pacchetto. I due formati più diffusi sono CycloneDX e SPDX: entrambi vanno bene per iniziare, la scelta conta meno rispetto al fatto di generarlo e conservarlo davvero ad ogni release.
argon2 è davvero meglio di bcrypt per l’hashing delle password?
Argon2id è il vincitore della Password Hashing Competition ed è oggi la raccomandazione di riferimento per nuovi progetti. bcrypt resta accettabile su sistemi legacy, ma per un nuovo sviluppo conviene partire direttamente da argon2id.
Come si collega A10 Mishandling of Exceptional Conditions all’incident response?
Una gestione degli errori che segue il principio “fail closed” riduce il numero di incidenti che arrivano fino al SOC, perché molte condizioni anomale vengono bloccate automaticamente invece di essere silenziosamente concesse.
Serve rifare tutta la remediation a ogni nuova edizione della OWASP Top 10?
No, ma conviene rivedere il mapping tra categorie vecchie e nuove, come nella tabella di questa guida, e verificare se i controlli esistenti coprono ancora le categorie che hanno cambiato definizione, in particolare A03 e A10.
Related Coverage
- OWASP Top 10 2025 vs API Security Top 10: 10 vs 10
- SBOM e Dependency Scan in Node.js: 12 Step, 40 Min
- CISA KEV: 16 Falle in 3 Settimane, 4 Critiche
- Wiz vs Orca Security: Minuti vs 24 Ore di Scansione
- SMS vs App vs Passkey vs Chiave Hardware: 5 Miliardi Attive
Per altri approfondimenti sulla sicurezza applicativa, consulta la sezione Sicurezza di shattered.io.



