Forma razonable de almacenar contraseñas encriptadas en la base de datos de una aplicación web, Linux

10

Esta pregunta es generalmente similar a las preguntas anteriores hechas aquí, pero no he visto ninguna relacionada con Linux.

Caso en cuestión: una aplicación web PHP tiene un backend MySQL. Como parte de su funcionalidad, accede a otros hosts remotos de MySQL y emite algunas consultas en esos hosts.

Para permitir eso, la aplicación PHP necesita credenciales para esas bases de datos remotas. ¿Cuál es una forma razonable para que almacene / obtenga dichas credenciales?

Se requiere que los usuarios de la aplicación no proporcionen dichas credenciales ellos mismos. Además, podría haber docenas de usuarios en esta aplicación.

Todos los usuarios de la aplicación se identifican a través de LDAP. La aplicación y todo el conjunto de servidores MySQL se encuentran dentro de la misma red interna (requiere verificación VPN de dos pasos). La configuración completa se ejecuta en máquinas Linux.

¿Cuáles son las soluciones razonables para este problema?

    
pregunta Shlomi Noach 13.01.2014 - 16:35
fuente

4 respuestas

13

Solo necesita almacenar la configuración en un archivo que solo sea accesible para el usuario con el que se ejecuta PHP. Puede evitar que un usuario web acceda al archivo, pero PHP debe poder acceder a las credenciales y, independientemente de lo que haga, estarán desprotegidas. Cualquier secreto que puedas dar a la aplicación podría ser descubierto, por lo que no hay ninguna ventaja real al tratar de hacer una cadena compleja.

Más allá del archivo de configuración, también debe asegurarse de que la cuenta SQL que utiliza su servidor web solo se pueda usar desde la IP del servidor web y que solo tenga los derechos necesarios para el servidor web. Si su servidor web es hackeado, entonces ellos obtendrán el acceso del servidor web a la base de datos, pero si su servidor web es así, también podrían simplemente reemplazar los scripts para que el servidor web acceda a él como quieran.

    
respondido por el AJ Henderson 15.01.2014 - 19:46
fuente
4

Supongo que estás en un servidor dedicado? Si estás en un alojamiento compartido, es casi imposible asegurar los scripts de PHP.

Un enfoque razonable es almacenar las contraseñas en un archivo de configuración dedicado y restringir los permisos del archivo para que este sea solo para el propietario .

Espero que la gente grite "oh, pero no están encriptados". La cosa es que su aplicación necesita las contraseñas de texto simple para conectarse a la base de datos. Entonces, si cifra las contraseñas, también necesita tener la clave disponible, lo que anula el punto. He visto todo tipo de propuestas locas para mejorar esto, pero todo lo que hacen es agregar complejidad sin agregar ninguna seguridad significativa.

    
respondido por el paj28 15.01.2014 - 19:41
fuente
1

Otra solución es implementar directamente un cliente ssh dentro de su aplicación y depender de bibliotecas de terceros como JSch o extenderlo ssh/ssh-agent para recibir y descifrar directamente la clave de su base de datos.

*EDIT*

Lo importante es lo que está intentando lograr al almacenar la clave en la base de datos cifrada.

Un atacante que pueda acceder al archivo de clave privada temporal también podrá leer la memoria del proceso del cliente ssh (y, por lo tanto, acceder a los datos clave), ya que ambos datos deben tener básicamente el mismo acceso. permisos: intentar ocultar el archivo no parece hacerlo más seguro.

Si está utilizando diferentes usuarios para la conexión db, webapp y ssh, al almacenar la clave en la db, descifrarla en la webapp y alimentarla a ssh, simplemente está abriendo posibles vectores de ataque distribuyendo la clave por todo el proceso. Si está utilizando un solo usuario para todos estos (db, app, ssh), no está ganando nada excepto por la complejidad del código.

La única ventaja parece ser una transferencia más fácil del sistema a un host diferente y una ganancia potencial en caso de que los datos de la base de datos sean robados, pero la aplicación web (que AFAIU contiene el algoritmo y la contraseña de descifrado) no. Pero ¿es probable?

Dicho esto, si desea proteger la clave, también puede usar el cifrado interno de las claves de ssh y cargarlas en un ssh-agent al iniciar su servicio (¡recuerde que debe eliminarlas cuando se detenga!). Pero recuerde nuevamente que ssh-agent mantiene las claves en la memoria sin cifrar, por lo que potencialmente puede ser leído. Una vez más, ¿es este el problema que estás tratando de resolver?

Si solo necesita proteger la comunicación entre dos máquinas, stunnel podría ser de mejor servicio que ssh.

    
respondido por el user32084 19.01.2014 - 20:51
fuente
0

Respuesta genérica sobre el título de la pregunta

Hay dos formas de hacer esto.

1. Tener la contraseña no almacenada en el servidor

Esto podría ser, pero, por supuesto, ¡nada podría funcionar sin esta clave esencial!

En este caso, el servidor de la aplicación debe solicitar la contraseña en cada inicio .

Esto requiere un administrador humano responsable de iniciar el servidor cada vez que ocurra una falla y / o el reinicio del servidor implemente de mantenimiento.

2. Tener la contraseña almacenada en el servidor.

Por supuesto, el nivel de derechos utilizado para servir páginas web no es el mismo que el nivel correcto para administrar el servidor.

Pero esto es lo único realmente importante.

Podrías hacer algo de endurecimiento: esconde la contraseña usando archivos ocultos, imagen stegano, o más, pero esto es un poco inútil:

Lo único importante es evitar la escalada de privilegios :

Una vez que el malvado alcanza un alto privilegio en su servidor, seguir paso a paso el proceso de arranque para recuperar la forma en que el servidor lo utiliza para leer su credencial es tan fácil como comer un pedazo de pastel .

Respuesta genérica sobre la aplicación desarrollada en GNU / Linux.

La forma más sencilla de garantizar el almacenamiento correcto de todas las credenciales en sistemas estructurados complejos es simplemente instalar Debian GNU / Linux con solo el sistema base , que instale solo los servidores requeridos siguiendo la documentación de Debian primero.

Una vez que todo está correctamente instalado, me tomo mucho tiempo para navegar por todos los documentos, antes de hacer mi propia configuración.

Llegó un paso de prueba, haciéndolos funcionar en mi dominio local.

Solo cuando creo haber comprendido suficientemente cómo funciona esto, podría colocarlo en una red pública.

    
respondido por el F. Hauri 20.01.2014 - 09:23
fuente

Lea otras preguntas en las etiquetas