Log Injection

In questo articolo trattiamo la Log Injection, una tipologia di attacco di per sé non grave, ma che può nascondere attacchi ben più importanti.

Il Log Injection (chiamato anche Log Forging) è una attacco in cui l’attaccante riesce a scrivere direttamente all’interno delle informazioni di tracciamento di un applicativo.

All’interno delle applicazioni c’è necessità di tenere traccia degli eventi per risolvere tempestivamente e in maniera efficace i possibili problemi futuri. Le applicazioni in genere utilizzano dei file di testo per memorizzare le informazioni sugli eventi accaduti nel sistema e in caso di problemi, tali log vengono analizzati. L’analisi dei log può essere manuale o automatizzata. L’analisi automatizzata viene utilizzata per filtrare le informazioni “quotidiane” dalle informazioni relativi ad eventi non ordinari o a problemi.

Un attacco di log injection può essere indirizzato al sistema di analisi, tramite l’inserimento di comandi, oppure utilizzato per coprire le tracce lasciate da un attacco precedente, molto più grave.

Spesso chi si occupa della manutenzione tende a creare log che (si spera) permettano di essere un buon supporto nella fase di sviluppo delle correttive. A volte vengono inseriti anche gli input provenienti dai form in cui digita l’input è deciso dall’utente.

Consideriamo l’esempio che segue e che trovate sul sito dell’OWASP.

Esempio


String val = request.getParameter("val");
try {
     value = Integer.parseInt(val);
}
catch (NumberFormatException) {
     log.info("Failed to parse val = " + val);
}

Il frammento di codice non è poi così raro, tuttavia sottintende la volontà del programmatore di porre rimedio velocemente a eventuali errori di conversione dei valori.

Risoluzione

Inserire direttamente gli input utente nei log è una misura estrema, che bisogna utilizzare con parsimonia.
Pertanto una prima soluzione al problema rimuovere l’istruzione che scrive il contenuto dell’input dell’utente direttamente nel log. Pertanto nel caso specifico il frammento che segue risulterebbe ugualmente valido:


String val = request.getParameter("val");
try {
     value = Integer.parseInt(val);
}
catch (NumberFormatException) {
     log.info("Failed to parse val");
}

Se è strettamente necessario salvare gli input utenti nei log, tali input vanno verificati. Spesso è più importante scrivere la causa dell’errore, e riferendoci all’esempio potremmo indicare il carattere non consentito che è stato utilizzato.

Fonti:

Owasp, log injection

La Sicurezza del software e la Path Manipulation

Con questo articolo avviamo una serie di articoli che tratteranno di sicurezza informatica, dal punto di vista della manutenzione software, iniziamo dalla Path Manipulation

In questi articoli voglio inquadrare il problema dal punto di vista della manutenzione del software, almeno per i problemi più classici. Dal punto di vista dello sviluppo, molte delle problematiche non sono più riscontrate poiché nei nuovi framework poiché adottano vi sono soluzioni built-in.

Spesso l’esistenza di vulnerabilità note da anni si può assimilare a errori di cattiva programmazione piuttosto che effettivamente a vulnerabilità dovute ad obsolescenza del software o della piattaforma. Alla luce dei motivi espressi trovo inutile a riportare semplicemente un decalogo “soluzione/risoluzione” del problema.

Spesso la sicurezza del software viene attuata istanziando un flusso con dei software che effettuano l’analisi statica e/o dinamica del codice sorgente del software d’interesse. A valle di tale analisi il software creerà delle segnalazioni relative alle vulnerabilità trovate, da valutare. Chiaramente la valutazione è d’obbligo sostanzialmente per due motivi:

  1. il software che effettua l’analisi potrebbe contenere a sua volta dei bug che possono far sì che le segnalazioni non siano corrette.
  2. il software che effettua l’analisi riporta la vulnerabilità solo se il calcolo effettuato è nel range di confidenza prefissato/configurato: questo vuol dire che se è riportata una segnalazione vuol dire che probabilmente vi è la vulnerabilità, non la certezza.

Il flusso così implementato nasconde un’ulteriore insidia: non verranno mai risolte quelle vulnerabilità che seppur presenti non vengono considerate: se l’elaborazione non rileva il problema oppure esso non è nel range di confidenza prefissato, la segnalazione non verrà mai effettuata e la vulnerabilità resta lì dov’è.

Un’ulteriore insidia (non meno pericolosa) è la stabilità del workflow instanziato.

Il workflow instanziato che viene istanziato al fine di migliorare la sicurezza del software non deve subire brusche evoluzioni, come il cambiamento della configurazione del software che effettua l’analisi, pena la risoluzione di vulnerabilità che possono essere considerate di “secondo piano” rispetto a vulnerabilità che possono essere rilevate mediante “la nuova configurazione” e viceversa.

La Path Manipulation (chiamata anche Directory traversal attack oppure path traversal attack) è una vulnerabilità per cui è possibile, tramite input esterni, leggere o scrivere in settori in cui non è previsto, nel sistema, la lettura e la scrittura dei file.

Il problema è molto serio: scrivere in particolari settori del file system può portare ad accessi (anche di tipo amministrativo) all’applicazione oggetto dell’attacco.

Per l’OWASP, la Path Manipulation si verifica quando si ottengono i seguenti effetti:

  1. l’attaccante può specificare un percorso utilizzato in un’operazione sul filesystem.
  2. Specificando la risorsa, l’attaccante ottiene dei privilegi che altrimenti che non sarebbero consentiti.

L’esempio triviale in questo senso è quello di consentire il nome del file dall’esterno dell’applicazione senza alcuna tipologia di filtro: tramite parametri esterni, un utente può definire il percorso di un file da cancellare o da modificare sul server.

Consideriamo un esempio di applicazione ASP.NET, in linguaggio C#:

Vogliamo effettuare la stampa di un report ed effettuiamo la chiamata di un report passando via GET (tramite url) il nome del report, cancellando il vecchio report eventualmente presente, il codice potrebbe presentarsi così:

[csharp]
String rName = Request.QueryString["reportName"];
string path = "C:\\Temp\\" + rName;
if (File.Exists(path))
{
File.Delete(path);
}
[/csharp]

Questo è un buon esempio di Path Manipulation: modificando opportunamente il parametro “rName” posso navigare nel filesystem e cancellare a piacere qualunque file.

Ad esempio se rName viene impostato a “..\psw.txt” la funzione File.Exist si assicurerà che esiste il file ed eventualmente l’istruzione delete lo può cancellare.

Esistono più soluzioni, tutte dipendenti dal contesto.

  1. Creare una WhiteList di valori ammessi in input: tale soluzione è definitiva ma spesso inapplicabile, poiché spesso i valori sono “arbitrari” e spesso vengono passati valori di input “di comodo” in fase di sviluppo.
  2. Creare una Blacklist di caratteri ammessi in input: in questo modo si delimita il problema alla cartella di riferimento, ovvero alla cartella “Temp” dell’esempio, in questo modo si limitano i possibili danni.

Spesso la soluzione più ragionevole da adottare è la 2, purché vengono adottate alcune osservazioni:

  1. Si contestualizza il flusso del software all’utente attualmente autenticato all’applicazione
  2. La cartella sia utilizzata solo come interscambio per rispondere alle richieste provenienti dall’esterno.

Esempio:

[csharp]

String rName = Request.QueryString["reportName"];
String nomeUtente = Session["Username"];
string path = "C:\\Temp\\" + nomeUtente + "\\" + rName;
if (File.Exists(path))
{
File.Delete(path);
}
[/csharp]

La cartella dedicata all’utente impedisce la cancellazione di file destinati agli altri utenti (potremmo avere anche un problema di lettura), inoltre se la cartella non sarebbe d’interscambio potrebbe essere cancellato o modificato un file necessario al funzionamento dell’applicazione stessa.

Link esterni/fonti di approfondimento:
Owasp
Wikipedia