Topic: Login db tramite GUI  (Letto 1333 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline tascio

  • python erectus
  • ***
  • Post: 188
  • Punti reputazione: 0
    • Mostra profilo
Login db tramite GUI
« il: Agosto 20, 2016, 15:51 »
Qual'è il modo migliore per fare un login ad un database?

cosi' su due piedi penso a questo
[codice]def _loginDB(self):
        #CONNESSIONE AL DB PER LOGIN
        try:
            conn = pymysql.connect(user="root",passwd="",host="localhost",
                                   port=3306,database="test")
        except:
            messagebox.showerror(message='Errore di connessione',parent=self)
        cursore = conn.cursor()
        cursore.execute("SELECT * FROM login")
        check = cursore.fetchall()
        l_ok=False
        for campo in check:
            #LOGIN OK
            if (campo[0] == self._usernameVar.get() and
                campo[1] == self._passwordVar.get()):
                messagebox.showinfo(message='Login effettuato con successo',
                                    parent=self)
                l_ok=True
                #MODIFICA IL BOTTONE LOGIN
                self._button['text']='Esci'
                self._button['command']=self._logoutDB
                break
        if l_ok==False:
            messagebox.showerror(message='Login Errato',parent=self)[/codice]

però in questo modo sto facendo scaricare il contenuto della tabella login al client, non è un problema di sicurezza gigantesco?  :O

qual'è il modo migliore?

Offline tascio

  • python erectus
  • ***
  • Post: 188
  • Punti reputazione: 0
    • Mostra profilo
Re: Login db tramite GUI
« Risposta #1 il: Agosto 20, 2016, 16:50 »
vabbè sono un cretino... invio i dati di login al server e li elaboro li stesso... come si cancellano i topic? xD

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.154
  • Punti reputazione: 9
    • Mostra profilo
Re: Login db tramite GUI
« Risposta #2 il: Agosto 21, 2016, 01:58 »
sì beh, non è che questo risolva poi tutto.

Offline tascio

  • python erectus
  • ***
  • Post: 188
  • Punti reputazione: 0
    • Mostra profilo
Re: Login db tramite GUI
« Risposta #3 il: Agosto 21, 2016, 18:42 »
ok, devo stare attento a cose tipo code injection, csrf ecc, ti riferisci a questo ric?

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.154
  • Punti reputazione: 9
    • Mostra profilo
Re: Login db tramite GUI
« Risposta #4 il: Agosto 22, 2016, 09:05 »
mah, se il tuo punto di partenza era: tiro giù dal server tutte le password di tutti gli utenti del database (potenzialmente milioni di dati sensibili, ovviamente non criptati) e confronto le password a una a una con un ciclo finché non trovo quella giusta, allora sì, direi che devi stare attento un po' a tutto.

Offline tascio

  • python erectus
  • ***
  • Post: 188
  • Punti reputazione: 0
    • Mostra profilo
Re: Login db tramite GUI
« Risposta #5 il: Agosto 22, 2016, 18:43 »
esiste un altro modo ric?
la mia idea è:
db con i dati di login (classico)
psw hashate, cosi' conservo l'hash e nn la password
client manda i dati al server, ed il server accede al db cerca il nome utente, se lo trova confronta gli hash della password

credo sia la procedura standard, ?_?

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.154
  • Punti reputazione: 9
    • Mostra profilo
Re: Login db tramite GUI
« Risposta #6 il: Agosto 23, 2016, 10:03 »
Non c'è una procedura standard, e il problema della "sicurezza" è molto vasto e riguarda molti aspetti. Ora, tu qui parli di conservare le password degli utenti, e va bene, questo è UNO DEI problemi del manuale in dieci volumi che si intitola "sicurezza". E' un'aspetto importante, beninsteso. Devi capire che gli utenti ri-utilizzano lo stesso login-e-password per molte cose diverse. Quindi, se qualcuno ruba dal tuo programma bacato qualche migliaio di password, ci sono ottime chance che abbia anche qualche centinaio di login per email, facebook, ebay, conti correnti con cui giocare. E il bello è che gli utenti neppure si rendono conto di averti affidato le chiavi di casa. Danno per scontato che il tuo programma sia sicuro... beata innocenza.
Quindi sì, l'idea è quella di conservare nel db solo delle rappresentazioni delle password, anziché le password vere e proprie. E come devono essere costruite queste rappresentazioni? Con un hash, si dice. E quale? sha256, parrebbe. Anzi no, sha512. Ma proprio no, meglio bcrypt. E poi naturalmente con un salt. Anzi no, ogni hash deve avere un salt diverso, univoco. E generato come? Uffa.
Poi naturalmente esistono anche le complicazioni pratiche. Che succede se l'utente dimentica la password? Bisogna offrirgli un modo automatico e SICURO per re-impostarla. Eccetera.

Comunque non è difficilissimo capire qual è la "procedura standard" per questo particolare paragrafo del manuale in dieci volumi intitolato "sicurezza". Basta googlare per "how to hash a password" o qualcosa del genere. L'importante è non fermarsi al primo articolo che si legge, capire bene, controllare di non star leggendo cose di dieci anni fa.
Dopo di che, in qualsiasi articolo serio sull'argomento trovi sempre scritto a caratteri cubitali l'avvertimento "non fatevi la sicurezza a mano", cioè con delle routine scritte da te. Meglio affidarsi a librerie, per queste cose. Se usi Django, il sottosistema django.user "fa la cosa giusta" (si suppone) senza che tu debba preoccuparti del problema. In ogni caso, una googlata per "python password hashing library" o qualcosa del genere potrebbe rivelare delle soluzioni.

E poi, visto che siamo nel 2016, magari conviene affidarsi del tutto a un sistema di autenticazione esterno. Hai presente, quando trovi "entra con Facebook", "entra con Twitter", "entra con Gmail". Ecco, quella cosa lì. Affidi a un servizio esterno il compito di verificare per te che l'utente sia proprio chi dice di essere. Si può fare, si può fare (anche in python). Questa cosa si chiama "social auth", quindi basta googlare qualcosa come "python social auth" o "django social auth" e vengono fuori delle cosette.


E questo è solo un aspetto. Ma poi ce ne sono infiniti altri. Tanto per considerare solo l'aspetto immediatamente adiacente... ok, supponiamo che l'utente abbia una password e che questa sia conservata nel tuo db in modo sicuro. Questa però è una password *per il tuo programma*, non *per il db* ovviamente. Voglio dire, quando metti su un database postgres (o diocenescampi un database mysql), tu hai un login da amministatore/superuser con cui crei il db e le tabelle, per dire. Poi il tuo programma si connette al database creato, giusto? A un certo punto nel tuo codice dovrai pur fare qualcosa come db.connect(db="foo/bar/db", user="pippo", pass="secret"), dico bene? E quale login utilizzi, per questo? Ovviamente non il tuo login di amministratore, si capisce. Ma altrettanto ovviamente NON il login dell'utente, giusto? Anche perché, al momento di connetterti al database, tu NON sai se il login dell'utente è quello giusto... ovvero, il tuo programma si deve connettere al database PRIMA che l'utente possa connettersi al tuo programma, chiaro? Altrimenti, come farebbe il tuo programma a pescare dal database i dati dell'utente per verificare la sua identità? Ops. Ma a parte questo, non vuoi usare il login dell'utente per connetterti al database perché a questo punto l'utente potrebbe connettersi al database direttamente, con una shell, fuori dal tuo programma. E non c'è bisogno di dire che questo non va bene.
Quindi, devi creare un login apposta perché il tuo programma possa connettersi al database. Ovviamente questo login sarà un utente-di-database con permessi inferiori a quelli del tuo login da amministratore, ma abbastanza alti da poter fare le cose che deve fare il tuo programma (non potrà creare tabelle, per esempio, ma potrà cancellare record, etc.). Ok, e quindi, DOVE conservi questa coppia di user/password, in modo che l'utente NON la scopra (e nessun altro, ovvio)? Chiaramente, NON la puoi scrivere semplicemente nel tuo codice. E quindi il tuo codice da dove pesca questa informazione?
Boh, dipende. Se il tuo codice gira su un server, potrebbe bastare mettere questi dati in un file (json, magari) che risiede in una directory NON esposta verso l'esterno (ovvero, dove il web server non va a ficcanasare) ma a cui il tuo programma HA accesso (ovvero, specifichiamo: una directory a cui ha accesso l'utente del sistema operativo sotto il quale viene eseguito il tuo programma). Se qualcuno compromette il server fino al punto da fare una escalation dei privilegi di utente del sistema operativo, accedere come admin e leggere quel file... boh, allora devi assumere che a questo punto potrebbe comunque fare quello che vuole con il tuo server, e questa non è più una responsabilità del tuo programma probabilmente.
Comunque, in genere vedo che ormai tutti i servizi di hosting come Heroku, eccetera, utilizzano un sistema più pratico ancora: ti permettono di creare delle variabili di ambiente del sistema operativo, che poi puoi interrogare da python con os.environ. Quindi il tuo programma si logga al database con db.connect(db="foo/bar/db", user=os.environ["DBUSER"], pass=os.environ["DBPASS"]) o qualcosa del genere. Nel tuo codice non ci sono dati sensibili, e chi vuole scoprirli dovrebbe riuscire a compromettere il server e leggere le variabili d'ambiente.
E se il tuo programma gira su un client? Boh, allora sei fregato, più o meno. Puoi offuscare quanto vuoi, ma in sostanza non c'è modo di nascondere qualcosa in una macchina che non ti appartiene. Dovunque nascondi della roba, l'utente per definizione può avere accesso. La macchina è sua. L'unica soluzione vera è di far girare comunque un servizio remoto sul server, che è quello che si connette al database, eccetera. Ma allora ti riporti nel caso precedente.

E questi sono solo i sommari di due paragrafi del manuale in dieci volumi. Ovviamente molti dei capitoli del manuale non ti riguardano personalmente. Voglio dire, se in ultima analisi il server è collocato fisicamente nel classico "stanzino del server" che è sempre aperto e ha un monitor con una sessione aperta dell'amministatore che è andato a pranzo, allora che cosa stiamo parlando a fare. Ma questo è un problema del sysadmin, non tuo. Se l'amministratore del database ha lasciato un postit con la sua password sul vetro dell'armadio dei rack, questo è un suo problema. Eccetera.