beh...il codice non sembra mancante di solidità, a prima vista.
Cmq, io non metterei in condizione all'utente di conoscere se sta sbagliato nome utente o la password.
Fai spuntare solo "nome utente e/o password errata"
Facendo in quel modo, ad un eventuale attacco tu dai la possibilità di sapere che un determinato utente è registrato o meno.
E' vero, è un pagliativo (ovvero, che se l'hacker vuole attaccare, basta che si registra e vede se un particolare username è stato usato)
Quindi, potresti usare l'email come login, anziché di un nome utente.
vedo che fai largo uso di questa cosa
md5(row["random"].$row["password"].$row["random"])
è bellissima. Appunto per questa crea una nuova funzione, così da non dover ripetere l'operazione
fai md5Improved($row)
sarà lui a richiamare la chiave password e random
questi sono i miei consigli