2009-04-08 12 views
35

Come si memorizza una password inserita dall'utente in memoria e la si cancella in modo sicuro dopo che non è più necessaria?Cancellazione sicura della password in memoria (Python)

Elaborare, attualmente abbiamo il seguente codice:

username = raw_input('User name: ') 
password = getpass.getpass() 
mail = imaplib.IMAP4(MAIL_HOST) 
mail.login(username, password) 

Dopo aver chiamato il metodo login, che cosa dobbiamo fare per riempire l'area di memoria che contiene la password con caratteri illeggibili in modo che qualcuno non può recuperare la password facendo un core dump?

C'è una domanda simile, tuttavia è in Java e la soluzione utilizza array di caratteri: How does one store password hashes securely in memory, when creating accounts?

questo può essere fatto in Python?

+0

Vicino alla parte inferiore di questo [articolo IBM] (http://www.ibm.com/developerworks/library/s-data.html?ns-311), si parla dell'utilizzo di una struttura dati mutevole anziché immutabile stringa. –

+0

Il collegamento all'articolo IBM nel commento sopra non funziona più, utilizzare una [pagina archiviata] (https://web.archive.org/web/20150308000622/http://www.ibm.com/developerworks/ biblioteca/s-data.html). –

risposta

37

Python non ha un livello di controllo troppo basso sulla memoria. Accettalo e vai avanti. Il migliore che si può fare è del password dopo aver chiamato mail.login in modo che non rimangano riferimenti all'oggetto stringa password. Qualsiasi soluzione che pretende di essere in grado di fare di più ti sta solo dando un falso senso di sicurezza.

Gli oggetti stringa Python sono immutabili; non esiste un modo diretto per modificare il contenuto di una stringa dopo che è stata creata. Anche se si fosse in grado di sovrascrivere in qualche modo il contenuto della stringa indicata da password (che è tecnicamente possibile con stupidi trucchi di tipo), ci sarebbero comunque altre copie della password che sono state create in varie operazioni di stringa:

  • dal modulo getpass quando strappa il nuovalinea fuori della password immessa
  • dal modulo imaplib quando cita la password e quindi crea il comando completo IMAP prima spacciandolo alla presa

Tu w in qualche modo dovremmo ottenere riferimenti a tutte quelle stringhe e sovrascrivere anche la loro memoria.

+9

Per non parlare della possibilità che il sistema operativo sostituisca l'intera pagina di memoria su disco, dove potrebbe rimanere per mesi. – JasonSmith

+0

Il problema dello swap non è specifico di py, ma qui c'è una discussione su quella parte: https://security.stackexchange.com/questions/29350/swap-file-may-contain-sensitive-data – Zitrax

-2

EDIT: rimosso il cattivo consiglio ...

È inoltre possibile utilizzare le matrici come l'esempio java, se volete, ma basta sovrascrivere dovrebbe essere sufficiente.

http://docs.python.org/library/array.html

+1

All password = "somethingelse" fa è rimuovere il riferimento alla vecchia password una riga in precedenza. In realtà non sovrascrive nulla. – Miles

+0

Capisco. Grazie per le informazioni. –

-2

Conservare la password in un elenco, e se è sufficiente impostare l'elenco su null, la memoria della matrice memorizzato nella lista viene liberato automaticamente.

+7

Il livello di ricerca indiretta di memorizzazione della stringa in una lista offre una protezione zero. – Miles

+2

Inoltre, non esiste alcuna specifica per cancellare la memoria dopo essere stata liberata. La memoria rimarrà intatta e sarà vulnerabile all'essere imaged o scambiato su disco nel tempo. – drifter

+0

C'è un bell'articolo sul perché questo non funziona correttamente: http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm – mkind

7

Se non è necessario che l'oggetto di posta persista una volta terminato, penso che la soluzione migliore sia eseguire il lavoro di mailing in un sottoprocesso (vedere il modulo subprocess). In questo modo, quando il processo secondario muore , così va la tua password.

17

In realtà esiste un modo per cancellare in modo sicuro le stringhe in Python; utilizzare la funzione memset C, come da Mark data as sensitive in python

+1

Si noti che questo è un SO -dipendente. Il codice Windows e Linux è indicato nel post collegato. – Luc

2

Ciò potrebbe essere fatto utilizzando chararray NumPy:

import numpy as np 

username = raw_input('User name: ') 
mail = imaplib.IMAP4(MAIL_HOST) 
x = np.chararray((20,)) 
x[:] = list("{:<20}".format(raw_input('Password: '))) 
mail.login(username, x.tobytes().strip()) 
x[:] = '' 

Si dovrà determinare la dimensione massima della password, ma questo dovrebbe rimuovere i dati quando vengono sovrascritti.

Problemi correlati