Proteger datos encriptados en caso de inyección SQL

5

Digamos que hay una aplicación web, con datos encriptados. p.ej. un sitio web donde los pacientes dejan notas a sus médicos.

Un paciente inicia sesión, deja una nota, esa nota se cifra con un cifrado simétrico y se inserta en la base de datos, el usuario todavía puede ver su nota si alguna vez regresa, la nota se descifra y puede verla. El médico inicia sesión, va a la nota de un paciente y se descifra e imprime.

Pero la aplicación es vulnerable a la inyección de SQL. Un hacker lo encuentra, abre una cuenta en la aplicación web y crea una nota falsa. Luego usa la inyección SQL y copia la nota encriptada de otra persona y pega su contenido (su fila en la tabla). Cuando vuelve a la aplicación para verla, se descifra.

¿Cómo puede evitar que el pirata informático vea otras notas encriptadas?

    
pregunta Mehdi 01.02.2018 - 13:22
fuente

7 respuestas

16

Si entiendo su pregunta correctamente, su sistema usa la misma clave para cifrar y descifrar el mensaje tanto para el paciente como para el médico.

En este caso, su ataque es teóricamente posible, suponiendo que pueda leer el mensaje de otro usuario e insertarlo en la base de datos como su propio mensaje.

La mitigación en términos de cifrado contra esto sería una clave única por usuario o el uso de pares de claves públicas / privadas para cifrar los datos y cada usuario volverá a tener una clave única para mayor seguridad y limitación de daños en caso de una infracción.

Otros mecanismos incluirían la defensa adecuada contra la inyección de SQL mediante la desinfección de la entrada y también un sistema de verificación del usuario para garantizar que cualquier usuario que se registre sea un paciente legítimo, esto reduce el grupo de atacantes, pero no se debe confiar solo.

    
respondido por el iainpb 01.02.2018 - 13:37
fuente
12

El problema aquí es que cada nota está cifrada con la misma clave de cifrado. Eso hace que la aplicación sea más vulnerable de lo que debería ser.

Considere esta configuración en su lugar:

  • Todos los usuarios, médicos y pacientes, tienen su propio par de claves público - privado.
  • Las claves públicas se almacenan cifradas con una clave amplia de la aplicación almacenada fuera de la base de datos.
  • Las claves privadas se almacenan encriptadas con una clave personal derivada de la contraseña del usuario.
  • Cada nota individual se cifra con su propia clave aleatoria única. Esa clave se almacena encriptada en dos versiones: una encriptada con la clave pública de los pacientes y otra con la clave pública de los médicos.

No tome esto como un plano para el sistema perfecto. Hay muchas maneras de hacer esto, y posiblemente mejores que esto. Pero es un ejemplo de un sistema donde el acceso de lectura y escritura solo a la base de datos (por ejemplo, en el caso de SQLi) no le daría al atacante acceso instantáneo a todos los datos de texto sin formato.

Editar: Si desea que todos los médicos puedan leer todas las notas, las cosas se ponen un poco más inestables. Cualquier persona con acceso de escritura a toda la base de datos podrá convertirse en un médico. ¡Así que debe restringir el acceso de escritura a la tabla de médicos lo más posible!

No le dé al usuario de DB la aplicación web que está usando el acceso de escritura a esa tabla, y use otro sistema más restringido (por ejemplo, solo disponible en algunas intranet) para crear nuevos médicos. O exija que cada fila en la tabla de médicos esté firmada criptográficamente o algo así. O incluso mejor, lea gran respuesta de Lie Ryans .

Conclusión: La lección para llevar aquí es que el cifrado requiere algo más que un algoritmo, un mensaje y una clave. Es cuando empiezas a pensar en cómo manejar las claves, las cosas se complican y necesitas soluciones que dependen en gran medida del contexto.

    
respondido por el Anders 01.02.2018 - 13:53
fuente
7

Creo que estás siendo demasiado absorbido por un ataque específico. Quiero decir, ¿le preocupa que un inicio de sesión de SQL que tenga acceso completo de CRUD a la tabla de notas (y posiblemente más) intente leer las notas de otros médicos?

  • ¿Qué pasa si eliminan selectivamente una nota para un día específico?
  • ¿Qué pasa si reemplazan una nota del médico con una que crearon?
  • ¿Qué pasa si cambian qué médico emitió una nota?
  • ¿Qué sucede si mezclan todas las notas e intentan tirar de una amenaza de ransomware?

Sí, sería bueno cifrar las notas de los médicos usando diferentes claves (incluso si es tan simple como: [AppWideKey] + [DoctorID]) Pero tu enfoque probablemente debería ser, "Si un ataque de inyección de SQL tiene éxito , el hacker iniciará sesión en SQL como AppUserX. ¿Cómo puedo minimizar el daño que puede hacer AppUserX? " Y la respuesta suele ser: haga que utilicen procedimientos almacenados para obtener sus datos, solo deje que los procesos almacenados hagan la cantidad mínima para cumplir con las necesidades de la aplicación y no le dé al usuario acceso directo a las tablas.

    
respondido por el Kevin 01.02.2018 - 16:44
fuente
6

Debes cifrar cada nota con su propia clave secreta. Debe usar una nueva clave simétrica para cada nota. Esta clave simétrica se denomina clave de sesión.

Ahora el problema es cómo distribuir la clave de sesión a los destinatarios y solo a los destinatarios. Para esto, necesitas criptografía de clave pública.

Debe emitir a cada participante en el sistema (pacientes y médicos) su propio par de llaves personal. La clave pública puede almacenarse en el servidor sin cifrar, pero la clave privada no debe almacenarse en el servidor sin cifrar. Debe cifrar la clave privada en el servidor con la contraseña del usuario, o se debe solicitar a los usuarios que almacenen su clave privada de forma segura.

Un paciente puede enviar un mensaje privado a un médico en particular generando una nueva clave de sesión y cifrando un mensaje con él, luego encriptando la clave de sesión con la clave pública del médico. También puede enviar un mensaje a múltiples destinatarios cifrando la clave de sesión contra múltiples claves públicas.

Opcionalmente, puede querer tener una Autoridad de Certificación que verifique la identidad de un participante (por ejemplo, solicitando una identificación con foto) y firme la clave pública del participante para afirmar que se realizó la verificación de identidad, y adjuntar atributos firmados que afirman la rol (es).

En este punto, tiene un mecanismo para el cifrado punto a punto, estos son esencialmente cómo funciona el esquema S / MIME y PGP.

Puede crear un mensaje grupal por encima de esto, para que los pacientes y / o médicos puedan enviar un mensaje a un grupo grande (por ejemplo, un paciente puede enviar un mensaje cifrado al grupo de podiatras, sin permitir que el grupo dental lea el mensaje), sin que nadie tenga que conocer la identidad del miembro individual. Esto se denomina cifrado multidifusión.

La forma en que creas mensajes de grupo es que necesitas crear un par de llaves de grupo. Un par de llaves de grupo consiste en una clave privada que se distribuye a todos los miembros del grupo y una clave pública que se distribuye a cualquiera que necesite enviar mensajes al grupo. Esto permite a los miembros y no miembros enviar un mensaje a todos en ese grupo solamente. Para enviar un mensaje de grupo, debe cifrar la clave de sesión para ese mensaje con la clave pública del grupo.

Tenga en cuenta que en la mayoría de los casos, deberá crear una nueva clave de grupo cada vez que cambie la membresía de un grupo (por ejemplo, alguien deja el grupo o una nueva persona ingresó al grupo).

    
respondido por el Lie Ryan 01.02.2018 - 16:56
fuente
1

El cifrado que usted describe no lo está protegiendo de muchos escenarios. Lo protegerá en caso de que la base de datos MySQL sea robada pero las claves de cifrado no lo sean. Pero como la base de datos está detrás de la aplicación, es la aplicación la que generalmente se rompe primero, y luego la base de datos, por lo que en el escenario de la vida real, ambas claves con la aplicación y la base de datos serían robadas.

Para proteger la aplicación de esto, necesitaría resolver la inyección de SQL, lo cual es fácil y directo. Es fácil asegurarse de que todas las aplicaciones sean resistentes a las inyecciones de SQL, todo lo que necesita es modificar cada consulta a la base de datos, por ejemplo. De esta manera está usando declaraciones preparadas.

No importa cuán grande y compleja sea la aplicación, o cuántos lenguajes y marcos de trabajo está usando, este es un trabajo simple y muy efectivo. Tener las inyecciones de SQL ordenadas es lo más básico que se debe hacer.

Hay muchas otras formas de evitar que un pirata informático haga lo que usted describe. Por ejemplo, las variables de auditoría pasadas a la aplicación, esto generalmente se realiza mediante algo llamado WAF, también puede incrustar la detección de ataques de Inyección SQL en su código en la parte superior de la cadena de procesamiento.

    
respondido por el Aria 01.02.2018 - 13:36
fuente
1

Si tiene controles de acceso sólidos en su lugar, solo el propio paciente podrá crear nuevas notas en su perfil. Un médico debe poder leer la nota y agregar comentarios a la nota, pero no eliminarla ni actualizarla. Esto debería hacer que la nota original sea inmutable: conceda la inserción de la aplicación pero no los privilegios de actualización en la tabla de notas. Esto también debería mitigar el ataque de inyección.

También puede asociar notas con sesiones de usuarios, de manera que un médico solo podría ver notas de un usuario asociado con sesiones válidas y no se mostrarían las inserciones realizadas a través de SQLi; un trabajo de normalización de la base de datos podría eliminarlas.

Para usuarios que pueden tener privilegios adicionales a través de la interfaz web, por ejemplo, como superusuario, puede limitar el acceso al recurso de superusuario a direcciones IP específicas (es decir, el sistema de la oficina central) utilizando httpd.conf o similar.

    
respondido por el AndyMac 01.02.2018 - 14:28
fuente
1

¿Está utilizando consultas parametrizadas? Esto debería evitar la inyección de SQL no sofisticada.

Debes tener 1 clave única por usuario. ¿Los usuarios se registran con una dirección de correo electrónico & ¿contraseña? Podrías usar la contraseña.

La generación de una clave para cada usuario cuando se registran y el almacenamiento en la base de datos suena estúpido. Solo agregaría 1 paso más requerido para realizar el ataque original. En realidad, ni siquiera debe almacenar la contraseña del usuario en la base de datos. ¿Eres tú? ¿Y estás usando HTTPS?

    
respondido por el user169799 01.02.2018 - 17:51
fuente

Lea otras preguntas en las etiquetas