c# - ¿Hay algún beneficio al usar SecureString en ASP.NET?
(5)
Si entiendo correctamente, esto es para mantener el texto sin memoria, para que la aplicación sea segura contra ataques esotéricos en la memoria, el montón de basura o la memoria paginada en el disco. SecureString se alimenta con bytes no administrados y consume un byte no administrado a la vez; luego, la cadena se borra de la memoria. (¡Corrígeme si me voy!)
En ASP.NET, el secreto se recopila en un formulario web, que se publica en HTTPS. Pero luego el objeto Request convierte todos los valores de solicitud del formulario en pares de nombre y valor y los coloca en una colección, por ejemplo, Request ["TxtPassword"], por lo que incluso antes de que pueda obtener la cadena, ya se ha escrito inseguramente en la memoria. Peor aún, si estuviera usando un control, la representación no segura tendrá más cadenas administradas en la propiedad del TextBox.
Para hacer algo con este SecureString, necesito una API que tome cadenas no administradas, por lo que parece que no puedo usar la cadena segura para un parámetro de proceso almacenado ni mucho más.
¿Lo estoy haciendo mal o es una tontería intentar usar SecureString y no filtrar copias de la cadena insegura en la memoria administrada?
Cambiar a la autenticación de OAuth o Windows no es una opción.
Como dedujo correctamente, y otros ya mencionados, tiene poco sentido usar SecureString para almacenar datos sensibles a la seguridad que provienen de un formulario ASP.NET, porque esos datos ya están presentes en la memoria en texto plano.
Sin embargo, existen otras situaciones en las que se recomienda el uso de SecureString
, ya que el programa crea los datos confidenciales y no deben permanecer en la memoria una vez que haya terminado de trabajar con él. Por ejemplo, crear un sitio de SharePoint mediante programación o transferir credenciales de autenticación de un sistema a otro.
En los viejos tiempos, era más fácil garantizar que la vida útil de los datos confidenciales fuera lo más breve posible. Podría asignarse en la pila y borrarse tan pronto como el programa haya terminado de usarlo:
char secret[512];
generate_secret(secret, sizeof(secret));
do_something_with(secret);
memset(secret, 0, sizeof(secret));
// Secret data is now gone.
Tal enfoque no es posible con cadenas administradas, sin embargo, principalmente porque:
- No están asignados en la pila,
- Son inmutables, por lo que no se pueden borrar,
- No son desechables, por lo que no hay garantía sobre el momento en que el GC liberará los datos. Puede que nunca se libere, dependiendo de las condiciones de la memoria.
SecureString
intenta resolver ese problema siendo mutable y desechable, lo que le permite a uno escribir:
using (SecureString secret = new SecureString()) {
GenerateSecret(secret);
secret.MakeReadOnly();
DoSomethingWith(secret);
}
// Secret data is now gone.
Creo que tienes lo básico. SecureString está diseñado desde el punto de vista de estar en el lado del cliente. Por lo tanto, para una aplicación WPF / Winforms (y tal vez Silverlight, no recuerdo si está allí) vale mucho, mientras que para una aplicación del lado del servidor, no tanto debido a no ser el primero en manejar la cadena.
La única vez que SecureString
uso que falta de SecureString
cuando SecureString
revisiones de código de seguridad, es en instancias donde los datos pueden ser encriptados por la aplicación y reutilizados.
Por ejemplo, cuando un backend de un sitio web necesita comunicarse con un tercero u otro recurso interno que requiera credenciales. Como no se pueden codificar, SecureString
cuando necesite compilar la solicitud (que también debe estar en TLS).
Otra alternativa es usar la API de protección de datos de Windows si es posible.
Tenga en cuenta que el propósito de SecureString
es mantener el contenido en la memoria el menor tiempo posible.
SecureString se utiliza mejor para asignar credenciales de red para llamadas directas entre sistemas. Es un hecho en la arena web que si la credencial ingresó a través de la web en texto plano, pero si tiene que devolver esa credencial a través de una llamada de credencial estándar (ftp, servicios de directorio, etc.), entonces usar SecureString no no duele como un método de paso. Aunque tiene razón en que la cadena ya está en su sistema de servidor en texto plano, al menos puede reducir la huella entre los sistemas. Si solo está usando esta contraseña localmente, entonces estaría de acuerdo en que SecureString probablemente no sea muy necesario.
Sin embargo, los buenos hábitos de seguridad nunca son una pérdida de tiempo.
Si no me equivoco, puede usar la siguiente solución para mantener la entrada fuera de la administración de cadenas de CLR: API web: ¿cómo acceder a los valores de formularios multiparte al usar MultipartMemoryStreamProvider?
Solo lea FormData en el método ExecutePostProcessingAsync (..) como ReadAsByteArrayAsync () y nunca se convierta en una cadena en el camino.
Todavía necesita https para mantener la entrada segura en el camino.