Vai al contenuto
New

DeepSeek V4.1 Flash free for 7 days: 10M tokens a day after a top-up of $10 or more. Until Nov 30.

How it works

Threat modeling con STRIDE: un primo modello di una web app

Impara i diagrammi di flusso dei dati, i trust boundary e le sei categorie STRIDE, poi modella un OWASP Juice Shop locale in Threat Dragon.

Intermedio11 min di letturaDi NotHoly

Che cos'è STRIDE

STRIDE è un elenco di sei categorie di minaccia: spoofing, tampering, repudiation, information disclosure, denial of service ed elevation of privilege. Microsoft lo usa nelle sue linee guida sul threat modeling. STRIDE non trova le minacce al posto tuo. Ti dà sei domande da fare su ogni parte di un progetto, così il risultato non dipende da quello che ti viene in mente in un dato pomeriggio.

Il metodo arriva prima della maggior parte degli strumenti di sicurezza. Uno scanner guarda un sistema in esecuzione. Un threat model guarda il progetto: quali componenti esistono, quali dati si muovono tra loro e dove cambia il livello di fiducia. Puoi cominciare con carta e penna prima che esista una riga di codice.

Perché conta

Molti fallimenti di sicurezza web sono errori di progettazione. Il server si fida di un prezzo inviato dal browser. Una route di amministrazione controlla che l'utente abbia fatto l'accesso ma non che sia un amministratore. Un file di log salva i token di sessione. Ciascuno di questi problemi si può correggere nel codice, ma spesso il codice rispecchia il progetto che ha ricevuto. Il problema comincia dal progetto.

L'OWASP Threat Modeling Cheat Sheet dice la stessa cosa. Devi capire i flussi di dati, i trust boundary e le altre parti del sistema prima di poter dire quali minacce si applicano. Un threat model mette per iscritto questa comprensione in una forma che altre persone possono rivedere.

Gli elementi di base

Diagrammi di flusso dei dati

Un diagramma di flusso dei dati (DFD) ha quattro tipi di elemento:

  • Entità esterne: persone o sistemi fuori dal tuo controllo, come il browser di un cliente.
  • Processi: codice che riceve, modifica o invia dati, come un'API web.
  • Archivi di dati: posti in cui i dati restano fermi, come un database o un file di log.
  • Flussi di dati: frecce che mostrano i dati in movimento tra gli altri tre.

Tieni il diagramma in una pagina. Se ne serve una seconda, probabilmente stai disegnando due sistemi.

Trust boundary

Un trust boundary è una linea in cui i dati passano da un posto con un certo livello di fiducia a uno con un livello diverso. Il tuo server sta dentro la linea. Un browser sta fuori, perché chi lo usa può modificare qualsiasi richiesta prima che ti arrivi. Ogni flusso che attraversa un trust boundary va validato, e la maggior parte delle minacce interessanti sta su quegli attraversamenti. Il cheat sheet di OWASP li descrive come probabili punti di attacco.

I trust boundary non sono solo i bordi della rete. Possono esserlo anche un processo che gira con un altro account del sistema operativo, un identity provider di terze parti o un database che accetta connessioni da più servizi.

Le sei categorie

Ogni categoria viola una proprietà di sicurezza.

Categoria Proprietà violata Domanda da fare
Spoofing Autenticazione Qualcuno può fingersi un altro utente, servizio o componente?
Tampering Integrità I dati possono cambiare in transito o a riposo senza che nessuno se ne accorga?
Repudiation Responsabilità Qualcuno può negare un'azione, senza una registrazione che dimostri il contrario?
Information disclosure Riservatezza Qualcuno può leggere dati che non dovrebbe vedere?
Denial of service Disponibilità Qualcuno può rendere questo componente lento o non disponibile?
Elevation of privilege Autorizzazione Qualcuno può fare più di quanto gli è consentito?

Corrispondono alle descrizioni nella documentazione di Microsoft sul threat modeling. Lo spoofing, per esempio, significa usare le informazioni di autenticazione di un altro utente.

Non tutte le categorie si applicano a tutti gli elementi. Una mappa di partenza comune, usata in molti strumenti di threat modeling, è questa: alle entità esterne spettano spoofing e repudiation; ai processi tutte e sei; agli archivi di dati tampering, repudiation, information disclosure e denial of service; ai flussi di dati tampering, information disclosure e denial of service. Usa la mappa come spunto. Se una categoria ti sembra irrilevante per un elemento, scrivi perché, così un revisore può contestarlo.

Come funziona, passo per passo

  1. Definisci il perimetro. Scrivi una frase che nomini il sistema, la versione e ciò che resta fuori. "La web app Juice Shop e la sua API, in esecuzione in locale, escluso il sistema operativo host" è sufficiente.
  2. Disegna il diagramma di flusso dei dati. Aggiungi entità esterne, processi, archivi di dati e flussi. Etichetta ogni flusso con ciò che trasporta.
  3. Disegna i trust boundary. Metti una linea ovunque la fiducia cambi di mano.
  4. Prendi un elemento alla volta e passa in rassegna le categorie. Per ogni categoria applicabile, fai la domanda della tabella e scrivi la minaccia in una frase breve. Una forma utile è chi fa che cosa e che cosa va storto: "Un token di sessione rubato permette a un attaccante di fare ordini al posto del cliente."
  5. Scegli una risposta per ogni minaccia: una mitigazione, un rischio che accetti con una motivazione scritta, o un trasferimento a un altro soggetto. Una minaccia senza risposta resta aperta.
  6. Salva il modello nel controllo di versione accanto al codice e fissa una data per riprenderlo in mano.

Per una piccola funzionalità, i passi da 1 a 5 possono richiedere un'ora. La prima volta aspettati di ridisegnare il diagramma almeno una volta. È normale.

Pratica: modella OWASP Juice Shop

OWASP Juice Shop è un'applicazione web volutamente insicura per la formazione. In questo lab non la attacchi. Disegni il suo progetto, elenchi le minacce e scrivi le mitigazioni. Le minacce nascono dalla lettura del progetto, non da un attacco all'applicazione.

Esegui il lab solo sulla tua macchina, in ascolto su 127.0.0.1. Se non hai ancora configurato il container, segui prima OWASP Juice Shop con Docker.

Prerequisiti

Ti servono:

Sulla macchina di prova usata per questo articolo, git --version ha stampato:

text
git version 2.49.0.windows.1

Passo 1: avvia il lab

bash
docker run --rm -d --name juice-shop-lab -p 127.0.0.1:3000:3000 bkimminich/juice-shop

La parte -p 127.0.0.1:3000:3000 pubblica la porta solo sull'interfaccia di loopback, quindi gli altri computer della tua rete non possono raggiungerla.

Conferma che la web app risponde:

bash
curl -sI http://127.0.0.1:3000/ | head -n 1

Sulla macchina di prova, la prima riga dell'output è stata:

text
HTTP/1.1 200 OK

Conferma che l'API risponde. Questa è una semplice richiesta GET per un elenco di prodotti:

bash
curl -s -o /dev/null -w "products %{http_code} %{content_type}\n" http://127.0.0.1:3000/api/Products

Output:

text
products 200 application/json; charset=utf-8

Controlla la versione riportata dall'applicazione:

bash
curl -s http://127.0.0.1:3000/rest/admin/application-version

Output:

text
{"version":"20.3.0"}

Quella è la versione riportata dall'immagine l'8 novembre 2026 sulla macchina di prova. La tua immagine potrebbe riportarne un'altra. Annota la versione che vedi, perché il threat model descrive una release specifica.

Passo 2: installa Threat Dragon

Scarica la build desktop per il tuo sistema operativo dalla pagina delle release, installala e aprila. I nomi dei menu nei passi qui sotto non sono stati verificati su una build di Threat Dragon per questo articolo, e cambiano tra una release e l'altra. Adattali a quello che mostra la tua build.

Passo 3: disegna il diagramma

Crea un nuovo threat model e aggiungi questi elementi:

  • Un attore esterno chiamato Browser, descritto come "browser del cliente, fuori dal nostro controllo".
  • Un processo chiamato Juice Shop web and API, descritto come "web app e API su 127.0.0.1:3000".
  • Un archivio di dati chiamato SQLite database, descritto come "file dei dati dell'applicazione".
  • Due flussi dal browser al processo: le richieste HTTP e, di ritorno, le risposte HTTP.
  • Due flussi dal processo all'archivio: le query SQL e le righe restituite.
  • Un trust boundary che separa il browser dal processo e dall'archivio.

Il modello dovrebbe avere questo aspetto:

text
Browser (external actor)
   |  HTTP requests and responses
   v
=================== trust boundary ===================
   Juice Shop web and API (process, 127.0.0.1:3000)
   |  SQL queries and rows
   v
SQLite database (data store)

Lo schizzo testuale è solo una guida. Il file vero è quello che salva Threat Dragon.

Il modello usa SQLite come archivio di dati. Controlla la documentazione del progetto per la versione che esegui, perché i dettagli sullo storage possono cambiare tra una release e l'altra.

Passo 4: elenca le minacce per ogni elemento

Applica la mappa di partenza vista prima. Il browser è un'entità esterna, quindi gli spettano spoofing e repudiation. A ogni flusso tra browser e API spettano tampering, information disclosure e denial of service. Il processo dell'API ha tutte e sei le categorie. L'archivio SQLite ha tampering, repudiation, information disclosure e denial of service.

Qui sotto trovi un esempio per categoria. Un modello reale ha più righe per ogni elemento.

Categoria Elemento Minaccia Mitigazione
Spoofing Sessione tra browser e API Un token rubato permette a qualcuno di agire come un cliente Durata breve dei token, controllo della firma a ogni richiesta, invalidazione dei token al logout, limite di richieste sui login
Tampering Flusso dal browser all'API Un cliente cambia il prezzo o la quantità in una richiesta di ordine Il server ricalcola i prezzi dal database e non si fida mai dei totali del client; valida lo schema della richiesta
Repudiation Processo degli ordini Un cliente dice di non aver mai fatto un ordine, e nessuna registrazione dimostra il contrario Audit log lato server degli eventi di ordine con ID utente, timestamp e ID richiesta; nessun segreto nel log
Information disclosure Flusso dall'API al browser Una risposta di errore rivela stack trace o campi interni Restituisci solo i campi di un'allowlist; messaggi di errore generici al client; dettagli completi solo nei log del server
Denial of service Endpoint di ricerca Molte ricerche costose rallentano il servizio per tutti Limiti di richieste per client, lunghezza massima della query e dimensione massima della pagina, timeout sulle query al database
Elevation of privilege Funzioni di amministrazione Un utente normale chiama un endpoint di amministrazione dopo aver cambiato un valore di ruolo Controllo di autorizzazione sul server a ogni richiesta, accesso negato per impostazione predefinita, ruolo letto dalla sessione lato server

Usa la documentazione del progetto per vedere quali debolezze include di proposito la tua versione. Descrivi ogni minaccia in termini di progettazione. Non scrivere nel modello i passi di un exploit. Questo lab non richiede alcun traffico d'attacco.

In Threat Dragon, aggiungi ogni minaccia all'elemento a cui appartiene, con un titolo, una descrizione e la mitigazione. Se la tua build ha un campo di stato, impostalo su aperto per le mitigazioni che non hai ancora implementato.

Passo 5: esporta e fai il commit

Esporta il modello in JSON dal menu file e chiama il file juice-shop-threat-model.json. Poi, nella cartella del lab:

bash
git init
cp /path/to/juice-shop-threat-model.json .
git add juice-shop-threat-model.json && git commit -m "First STRIDE model"

Git stampa un breve riepilogo con il nome del branch e il messaggio di commit. Il testo esatto dipende dalla versione e dalle impostazioni di Git. Se Git chiede un'identità, imposta la tua con git config user.name e git config user.email, e fai il commit con il tuo nome.

Prima del commit, leggi il file. Non dovrebbe contenere nomi host reali, token o dati di clienti. Questo modello usa solo 127.0.0.1.

Ferma il lab quando hai finito:

bash
docker stop juice-shop-lab
curl -s -o /dev/null -w "%{http_code}\n" --max-time 2 http://127.0.0.1:3000/

Sulla macchina di prova, l'output è stato:

text
juice-shop-lab
000

La prima riga viene da docker stop. Il 000 significa che curl non ha ricevuto risposta dalla porta, quindi il lab è spento.

Un threat model è un documento vivo

Un threat model descrive un progetto nel giorno in cui l'hai scritto. Quando il progetto cambia, il modello è superato. Tra le cause più comuni ci sono:

  • un nuovo endpoint o un nuovo ruolo
  • un nuovo provider di login
  • un database spostato su un altro servizio, che aggiunge un flusso di rete e forse un nuovo trust boundary
  • un nuovo tipo di dati, come dati di pagamento o dati personali
  • una dipendenza che ora gira con più accessi di prima

Il Threat Modeling Manifesto dice che il threat modeling dovrebbe seguire le modifiche al progetto, per iterazioni, ciascuna limitata a una parte gestibile del sistema. In pratica servono tre abitudini. Tieni il file JSON nel repository accanto al codice. Aggiungi una domanda di revisione alle pull request che toccano autenticazione, flussi di dati o integrazioni esterne: il threat model corrisponde ancora? Registra la data e la versione dell'applicazione descritte dal modello. Le minacce segnate come mitigate restano uno storico utile, quindi conservale.

Errori comuni

  • Disegnare il sistema che vorresti avere. Disegna quello che gira, compresi il proxy, la cache e i job in background.
  • Partire dall'intera azienda. Parti da una funzionalità e da un flusso, poi allarga.
  • Elencare minacce senza mitigazioni o responsabili. Una minaccia senza risposta resta aperta.
  • Scrivere una mitigazione come "usare la cifratura" senza dettagli. Di' che cosa è protetto, dove e come si controlla.
  • Tralasciare le frecce. La maggior parte delle minacce sta sui flussi e sui trust boundary, non dentro i riquadri.
  • Trattare le sei categorie come una lista da spuntare. Sono spunti. L'output utile è una decisione per ogni minaccia.
  • Sondare sistemi non tuoi per confermare una minaccia. Il modello non richiede test dal vivo, e qualsiasi test va fatto in un lab che gestisci tu.

Per andare oltre

  • Leggi fianco a fianco l'elenco delle minacce di Microsoft e il cheat sheet di OWASP. Annota dove concordano sulle categorie e dove la formulazione è diversa.
  • Modella una funzionalità di un progetto che mantieni, come il login o il reset della password.
  • Continua con OWASP Top 10 per sviluppatori. Elenca le debolezze web che incontrerai più spesso, e si adattano bene alle righe della tua tabella.
  • Sappi che esistono altri metodi, come gli attack tree e i metodi centrati sulla privacy, per le domande a cui STRIDE risponde meno direttamente.

Fonti

Fonti

  1. Microsoft Learn: Threat modeling tool threats
  2. OWASP Threat Modeling Cheat Sheet
  3. OWASP Threat Dragon
  4. Threat Modeling Manifesto
  5. OWASP Juice Shop project
  6. Docker port publishing

Altro su Fondamenti di sicurezza