2009-04-08 22 views
35

¿Cómo se almacena una contraseña introducida por el usuario en la memoria y se borra de forma segura después de que ya no sea necesaria?Borrado seguro de la contraseña en la memoria (Python)

Elaborar, en la actualidad tenemos el siguiente código:

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

Después de llamar al método login, ¿qué tenemos que hacer para llenar el área de memoria que contiene la contraseña con caracteres sin sentido para que alguien no puede recuperarse la contraseña haciendo un volcado de memoria?

Hay una pregunta similar, sin embargo, es en Java y la solución utiliza matrices de caracteres: How does one store password hashes securely in memory, when creating accounts?

se puede hacer esto en Python?

+0

En la parte inferior de este [artículo de IBM] (http://www.ibm.com/developerworks/library/s-data.html?ns-311), hablan sobre el uso de una estructura de datos mutable en lugar de una estructura inmutable cuerda. –

+0

El enlace al artículo de IBM en el comentario anterior ya no funciona, use una [página archivada] (https://web.archive.org/web/20150308000622/http://www.ibm.com/developerworks/ library/s-data.html). –

Respuesta

37

Python no tiene ese bajo nivel de control sobre la memoria. Acéptalo y sigue adelante. El mejor que puede hacer es del password después de llamar al mail.login para que no queden referencias al objeto de cadena de contraseña. Cualquier solución que pretenda ser capaz de hacer más que eso solo le da una falsa sensación de seguridad.

Los objetos de cadena Python son inmutables; no hay una manera directa de cambiar el contenido de una cadena después de que se crea. Incluso si fue capaz de sobrescribir de alguna manera el contenido de la cadena referida por password (que es técnicamente posible con estúpidos trucos ctypes), todavía habría otras copias de la contraseña que se han creado en varias operaciones de cadena:

  • por el módulo getpass cuando se despoja a la nueva línea de arrastre fuera de la contraseña introducida
  • por el módulo imaplib cuando se cita la contraseña y después crea el comando completo IMAP antes de hacerlo pasar a la toma

tu w De alguna manera, debería obtener referencias a todas esas cadenas y sobrescribir su memoria también.

+9

Sin mencionar la posibilidad de que el SO intercambie toda su página de memoria al disco, donde podría permanecer durante meses. – JasonSmith

+0

El problema de intercambio no es específico de python, pero aquí hay un debate sobre esa parte: https://security.stackexchange.com/questions/29350/swap-file-may-contain-sensitive-data – Zitrax

-2

EDIT: eliminado los malos consejos ...

También puede utilizar matrices como el ejemplo de Java, si se quiere, pero simplemente sobrescribir debería ser suficiente.

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

+1

Todas las contraseñas = "algo así como" lo hace es eliminar la referencia a la contraseña anterior una línea anterior. En realidad, no sobrescribe nada. – Miles

+0

Ya veo. Gracias por la info. –

-2

almacenar la contraseña en una lista, y si se acaba de establecer la lista a null, el recuerdo de la matriz almacenada en la lista se libera automáticamente.

+7

El nivel de indirección de almacenar la cadena en una lista ofrece protección cero. – Miles

+2

Además, no hay ninguna especificación para borrar la memoria después de ser liberada. La memoria permanecerá intacta y será vulnerable a imágenes o intercambios en el disco a lo largo del tiempo. – drifter

+0

Hay un buen artículo sobre por qué esto no funciona correctamente: http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-alarge-object.htm – mkind

7

Si no necesita que el objeto de correo persista una vez que haya terminado con él, creo que su mejor opción es realizar el trabajo de correo en un subproceso (consulte el módulo subprocess). De esa forma, cuando el subproceso fallezca , así es tu contraseña.

17

En realidad, hay una manera de borrar de forma segura cadenas en Python; utilizar la función memset C, según Mark data as sensitive in python

+1

Tenga en cuenta que este es el sistema operativo -dependiente. El código de Windows y Linux se proporciona en la publicación vinculada. – Luc

2

Esto podría hacerse utilizando 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[:] = '' 

Habría que determinar el tamaño máximo de la contraseña, pero esto debería eliminar los datos cuando se sobrescribe.

Cuestiones relacionadas