Alcance y seguridad variables

1

Esta pregunta está dirigida al marco .Net, pero se espera que sea respondida para abarcar muchos idiomas y amp; marcos.

Supongamos que tengo dos métodos, uno que en realidad descifra los datos y otro que toma los datos descifrados y los devuelve al usuario:

private string Decypt_Data(string encryptedText, string EncryptionKey) {

    string plainText = "";
    using(SomeEncryptionClass  myObject = new SomeEncryptionClass()) {

        myObject.Key = EncryptionKey;  //lets not worry about how we create or store these
        myObject.IV = GetIV();

        plainText = myObject.DecryptText(encryptedText);  

    }

    return plainText;  //REFERENCE 1

}

//specifically this is called from a controller after a POST
private ActionResult Read_Encrypted_Value()
{

    string encryptedEncryptionKey = GetDataFromDatabase("keyfield");
    string encryptionKey = Decypt_Data(encryptedEncryptionKey, GetKeyFromSomeWhereThisIsUnImportant());

    //decrypt data with plainText (ie. plainText is a key.. but this isnt important to the question)
    syromg encryptedData = GetDataFromDatabase("datafield");

    return View(Decypt_Data(encryptedData, encryptionKey));   //RFERENCE 2

}   

Mirando el método Decrypt_Data, el texto encriptado se pasa y se desencripta y luego se devuelve el texto sin formato.

La pregunta es ... ¿qué tan seguro es el valor almacenado en "plainText" (en la REFERENCIA 1)?

La variable plainText solo dura el alcance del método ... pero, ¿entonces qué? ¿Permanece ese valor en la memoria hasta que el recolector de basura se ocupa de él? ¿Se anula o algo así? ¿Debo hacer algo como en la REFERENCIA 2, donde hago el cálculo y devuelvo el valor juntos? ¿Debo pasar cadenas como referencias, para que no sea necesario crear una instancia de la variable que devuelve el valor?

Si el valor permanece en la memoria, ¿no es vulnerable? ¿Puede un atacante no leer la memoria y robar el valor? (Estoy trabajando en el principio de que este valor se utiliza para descifrar algunos otros datos ... para que el atacante que tiene acceso directo a la base de datos no le dé todos los datos).

La respuesta

Muchas gracias a todos por sus respuestas, encontré este artículo: enlace en uno de los enlaces de la respuesta del usuario10008. Cubre prácticamente todo lo que necesita saber + lista de códigos completa.

    
pregunta binks 11.09.2014 - 14:25
fuente

3 respuestas

0

Tiene razón, este es un problema común para el manejo de código de datos confidenciales. En el entorno administrado por .Net, incluso si usted hubiera puesto a cero su cadena, todavía tendría problemas, debido a movimiento de la cadena como resultado de la recolección de basura . El recolector de basura desea desfragmentar el montón y, por lo tanto, puede mover su cadena alrededor. Mover, por supuesto, no pone a cero los datos, es más bien copiar. Por lo tanto, debe indicar al GC que "sujete" la cuerda en particular para evitar que se mueva. Vea el enlace anterior sobre cómo hacer eso.

Y no, los datos no se ponen a cero, es posible que cuando su programa salga (o antes de que libere memoria), esta memoria esté disponible para otros procesos posiblemente hostiles.

SecureString puede almacenar los datos de una manera segura, pero aún debe interactuar con el mundo exterior. Esta pregunta cubre ese tema.

    
respondido por el user10008 11.09.2014 - 15:10
fuente
0

Esto realmente depende del idioma, si se compila entonces qué compilador se usó.

  

La pregunta es ... qué tan seguro es el valor almacenado en "plainText" (en   REFERENCIA 1)?

Sin usar una clase segura especial, esta variable residirá en la memoria hasta que se sobrescriba. No todos los idiomas proporcionan una "clase segura" para los datos. La liberación de memoria no siempre implica la puesta a cero de la memoria. Solo invalida el puntero con el administrador de memoria. Algunos recolectores de basura podrían poner a cero la memoria automáticamente, por supuesto, C no pondrá a cero nada cuando libere la memoria.

  

Si el valor permanece en la memoria, ¿no es vulnerable?

Todavía es vulnerable a las lecturas de memoria. Si esa parte de la memoria no se sobrescribe y un atacante lee esa memoria, el texto sin formato estará allí. Esto también se aplica incluso si el programa se ha cerrado.

La mejor manera de mitigar este problema en general es limitar el alcance de los datos confidenciales y sobrescribir la memoria cuando termine de usarla. Puede ponerlo en cero, puede sobrescribirlo con datos aleatorios, lo que desee. De esta manera, cuando la memoria se ve fuera de su alcance, no hay datos confidenciales.

En .NET, el recolector de basura sobrescribirá la memoria de los objetos muertos cuando las variables dejen alcance. Este artículo de 2 páginas explica .NET Garbage Collection

  

Una vez que los objetos muertos han sido identificados, el recolector de basura   comienza un nuevo procedimiento. Esto mueve los objetos vivos dentro del montón,   sobrescribir la memoria utilizada por los objetos muertos para eliminar elementos muertos   y volver a hacer el montón contiguo.

Yo todavía sobrescribiría los datos para estar seguro (si es posible, depende del idioma). Pero también soy un poco paranoico.

    
respondido por el RoraΖ 11.09.2014 - 15:18
fuente
-1

En .Net puede usar una cadena segura para tener un cierto nivel de protección contra la lectura de la memoria: enlace

    
respondido por el Louis Nadeau 11.09.2014 - 14:57
fuente

Lea otras preguntas en las etiquetas