OWASP, acronimo di Open Web Application Security Project, è un progetto e un'organizzazione no-profit che ha l'obiettivo di realizzare linee guida, strumenti e metodologie per migliorare la sicurezza delle applicazioni.
Tra i progetti più rilevanti abbiamo la OWASP top ten, ovvero una raccolta, riconosciuta a livello globale dagli sviluppatori come il primo passo verso una realizzazione di software più sicuro. Mira a sensibilizzare sulla sicurezza delle applicazioni identificando alcuni dei rischi più critici per le organizzazioni.
Di seguito un esempio visuale di top ten:
e di come è cambiata tra il 2017 e il 2021. Alcune criticità hanno innalzato il loro livello di popolarità, altre lo hanno abbassato, altre sono completamente nuove.
Il professore ha fornito una classifa OWASP di un periodo non chiaro che stiliamo di seguito:
Per la spiegazione di questo attacco si suppone che il lettore conosca SQL e i database.
Supponiamo di avere un database in cui vogliamo che vengano salvate le credenziali degli utenti che si iscrivono ad un certo sito web. Supponiamo che tale sito web gestista le richieste proveniente da Internet con PHP. Quando un utente effettua il login ad una piattaforma inserisce nome utente e password, tali dati devono essere poi cercati nel database per verificare che effettivamente esistano all'interno di esso.
In PHP abbiamo bisogno per prima cosa di istaurare una connessione con il database:
fucntion getDB() {
$dbhost="localhost";
$dbuser="root";
$dbpass="seedubuntu";
$dbname="dbusers";
// creazione della connessione con il db
$conn = new mysqli($dbhost, $dbusr, $dbpass, $dbname);
if($conn->connect_error){
die("Connessione fallita" . $conn->connect_error - "\n");
}
return $conn;
}
php
avendo la funzione per connettersi al database, adesso ci serve la funzione che gestisce le richieste ricevute da Internet (per esempio richiesta di login) e in particolare abbiamo bisogno che venga generata una query per effettuare la ricerca all'interno del database.
/* getData.php */
<?php
$eid = $_GET['EID'] // preleva l'username inserito dall'utente
$pwd = $_GET['Password'] // preleva la password inserita dall'utente
$conn = getDB(); // chiamata alla funzione per la creazione della connessione con il db
$sql = "SELECT Name, Salary, SSN
FROM employee
WHERE eid = '$eid' and password = '$pwd'"
$result = $conn->query($sql); // esegue la query sul db
if($result){
while($row = $result->fetch_assoc()) {
printf("Name: %s --- Salary: %s --- SSN: %s\n", $row["Name"], $row["Salary"],
$row["SSN"]);
}
$result->free();
}
$conn->close();
?>
php
Nella query sopra, vengono mostrati i dati relativi ad un certo impiegato, solo se username e password inserite sono corrette.
La query sopra, viene completata con dei dati inseriti dall'utente, in questo caso username e password.
Quindi è come se avessimo qualcosa come:
Dove gli spazi vuoti sono i punti che effettivamente andiamo a riempire con i dati che invia l'utente nella richiesta GET. Il che vuol dire che l'utente può effettivamente inserire ciò che gli pare tra quegli spazi. L'autenticazione poi andrà a buon fine se la combinazione di user e password è corretta, altrimenti fallirà.
Il punto è che un attaccante, con buone conoscenze dei database, ha ben chiaro il modo in cui si formano le query. Quindi può pensare di inserire dei caratteri che in qualche modo gli consentono di modificare la richiesta della query stessa.
Modi di manipolare la query sopra:
Un attaccante potrebbe inserire un certo user ID: EID5002, dopo può chiudere l'apostrofo inserendo ' e aggiungere anche #. L'input dell'attaccante diventerebbe: EID5002 ' #. Il simbolo di hashtag commenta il resto della query, dunque in questo caso, basta azzeccare l'user ID e non inserire alcuna password per visualizzare i dati degli impiegati.
Un'altra manipolazione:
L'attaccante può inserire a' OR 1=1. Dove a è un carattere a caso. Il vero problema è 1=1 che rende la query sempre verificata, mostrando quindi i dati per tutti gli impiegati.
Questo attacco si può evitare effettuando una buona sanificazione degli input inseriti dall'utente.
XSS è un attacco di tipo injection. In genere coinvolge tre entità:
Tipicamente le pagine web della vittima, provenienti dal sito web scelto come target sono protette da credenziali di login, sessioni di cookie, ecc. Normalmente è difficile per un attaccante infettare queste pagine. Un modo per farlo è iniettare codice nel browser della vittima.
Inserire un pezzo di codice nel browser della vittima non è poi così complesso. Tutte le volte che un utente visita la pagina del malintenzionato, il codice javascript della pagina dell'attaccante viene eseguito nel browser della vittima.
I browser attraverso delle sandbox (ambienti sicuri e isolati) impediscono il fatto che il codice eseguito sul browser di un utente (navigando tra le pagine dell'hacker) possa danneggiare o manipolare le pagine web di qualsiasi altro sito web o le interazioni dell'utente con essi.
Per causare danni alla vittima, correlati al sito scelto come target, il codice deve provenire dal sito target stesso.
L'attaccante deve trovare un modo di iniettare il suo codice malevolo nel browser della vittima attraverso il sito scelto come target. Questo tipo di attacco è chiamato cross-site scripting.
La figura mostra che in XSS il codice malevolo deve attraversare (cross) il sito web target per poi raggiungere il browser della vittima, dove viene eseguito
Ci sono due modalità per l'attaccante di effettuare tale iniezione:
Molti siti hanno comportamenti riflettenti. Per esempio, prendono in input dati da un utente, fanno alcune attività e poi inviano una risposta all'utente, con l'input originale inviato dall'utente stesso. Per esempio quando effettuiamo una ricerca su Google, utilizzando parole inesistenti, il risultato della pagina Google di solito contiene una frase del tipo: nessun risultato trovato per fdhsadkj. L'input viene riflesso verso l'utente.
Se un sito non effettua la cosiddetta sanificazione (validazione) dell'input correttamente, potrebbe essere vulnerabile ad un attacco di tipo XSS. Un attaccante può inserire del codice nell'input, così che esso venga riflesso verso l'utente. Va notato che l'input contenente il codice malevolo, deve essere inviato dal computer della vittima, in modo che la pagina web con il codice inserito possa essere inviata al browser della vittima e per essere eseguito con i privilegi della vittima.
La figura sopra mostra un attacco XSS. Assumiamo che il servizio vulnerabile sia il sito:http://www.example.com/search?input=word
dove word
è un dato inviato dall'utente.
L'attaccante può inviare il seguente URL alla vittima:http://www.example.com/search?input=<script>alert("attack");</script>
Una volta che la vittima clicca sul link, una richiesta di tipo HTTP GET viene inviata al sito www.example.com
, che ritorna una pagina contenente il risultato della ricerca, con l'input originale incluso nella pagina. Il codice inserito nel link verrà eseguito con successo nel browser della vittima, all'interno del sito target.
Nell'esempio sopra, la vittima vedrà semplicemente un alert in cui apparirà "attack".
L'attacco può essere utilizzato per intercettare i cookie.
Un attacco XSS persistente consente agli attaccanti di inviare i loro dati ad un certo sito target che salva i dati in una base di dati (o qualsiasi forma di salvataggio di dati persistente). Il sito, successivamente, mostrerà (faremo un esempio a breve) tali dati inseriti dall'attaccante, consentendo loro di rubare i dati di tanti altri utenti che visualizzano quei dati. Ora i dati inseriti dall'attaccante sono degli script malevoli scritti per esempio in javascript. Con "quando il sito web li mostrerà" vogliamo dire che, prendiamo in esempio un forum, se un utente (con cattive intenzioni) pubblica uno script come commento ad un post, il sito target salva quel commento in una base di dati, mostrando il post, successivamente, ad altri utenti, se il sito non ha sanificato il commento del malintenzionato, quando gli utenti visiteranno la pagina in cui risiede tale commento, eseguiranno il codice inserito dall'attaccante.
Un attacco CSRF (Cross Site Request Forgery) coinvolge tre parti: una vittima, un sito scelto come target e un sito web controllato dall'attaccante. La vittima ha una sessione attiva con il sito target mentre visita il sito web dell'attaccante. Il sito web malevolo crea una richiesta HTTP cross-site (ovvero una richiesta che è creata in ambiente al di fuori dal sito web in cui deve essere utilizza, cioè il sito target) verso il sito web target. Per esempio, se il sito web scelto come target è un social network, la pagina web malevola può creare una richiesta per l'aggiunta di un amico. Dal momento che il browser aggiungerà in automatico tutti i cookie alla richiesta generata dal sito malevolo (poiché l'utente ha una sessione attiva nel sito target), quando il sito target riceve la richiesta, se non ha modo di capire che è una richiesta malevola la processerà normalmente. La figura di seguito illustra il procedimento.
Per effettuare un attacco CSRF, l'attaccante ha bisogno di creare un sito web che crei la richiesta cross-site da inviare al sito web target. Inoltre, l'utente dovrebbe essere già loggato nel sito target; altrimenti, anche se l'attaccante può inviare richieste cross-site, il server del sito target non le processerà. L'attaccante potrebbe prima richiedere (nel suo sito web fasullo) alla vittima di effettuare il login. Questo dovrebbe risultare sospetto ad un utente.