Forma segura de establecer conexiones de base de datos PHP

3

He leído el consejo ( ejemplo : guárdelos en un archivo php en una ubicación inaccesible como una URL, pero no puedo evitar pensar que debe haber una mejor manera de almacenar / acceder a las credenciales de la base de datos.

Idealmente, sería imposible para alguien con acceso a los archivos del servidor web obtener las credenciales de la base de datos. Esto deja el desafío de cómo el servidor web obtiene una conexión de base de datos ...

Si hubiera una manera de pasar un objeto de conexión PDO entre dos scripts no relacionados, podría ser posible.

por ejemplo

  1. el script del sitio web principal, que se ejecuta como www-data necesita una conexión db

  2. de alguna manera realiza una llamada a una función php que existe en un archivo que no se puede leer con www-data.

  3. esa función decide si se debe permitir que el script acceda a la base de datos (por ejemplo, utiliza un seguimiento de depuración, crea md5sums (o similar) de todos los archivos mencionados, los compara con los protegidos, conocidos, buenos) y si pasa esta prueba, establece una conexión y devuelve el objeto PDO.

  4. el script web principal puede usar el objeto PDO, pero no puede extraer las credenciales.

¿Hay alguna forma de crear una biblioteca de PHP que se haya cargado antes, pero fuera de la ejecución del script principal? p.ej. añadir a stock libs? Esto haría posible este tipo de cosas.

¿O hay una mejor manera?

    
pregunta artfulrobot 21.05.2013 - 17:01
fuente

2 respuestas

2

Si su modelo de ataque permite que los "atacantes carguen sus propios scripts", entonces tienen acceso a todo lo que esos mismos scripts pueden ver o hacer , y "acceso seguro a la base de datos", por este valor de seguro , simplemente no es posible .

(Aparte de rediseñar la base de datos para que pueda ejecutar una comprobación de todos los archivos PHP involucrados en una conexión dada, aunque teóricamente sea posible, sería extremadamente difícil; solo piense lo que significa identificar los scripts de PHP, incluido por una Web proceso , que abrió una conexión, de la cual el servidor DB solo conoce la fuente dirección y puerto ! - y muy probablemente un asesino de rendimiento)

Pero en este punto, puede mover algo de lógica del servidor web, que se considera poco confiable, y ver qué seguridad se puede encontrar en otra parte.

Por ejemplo, puede hacer que los diferentes niveles de acceso de las aplicaciones web utilicen diferentes credenciales; es posible que tenga tres usuarios de la base de datos "invitado", "usuario" y "administrador". Puede organizar las cosas para que, por ejemplo, la administración de usuarios por el usuario admin no se realice en el mismo servidor web (puede separarlo por usuario de proceso, en un webroot, otra máquina virtual o un servidor web físicamente separado).

La mayoría de las funciones y consultas se pueden replicar utilizando procedimientos y funciones de alto privilegio que pueden acceder a los datos subyacentes a los que los usuarios de la web no tienen acceso : por ejemplo, puede realizar comprobaciones de inicio de sesión con una función:

DELIMITER //
CREATE FUNCTION is_valid_user(user varchar(32), pass varchar(32))
returns BOOLEAN
DETERMINISTIC SQL SECURITY DEFINER
BEGIN
DECLARE ret BOOLEAN;
SELECT 1 = COUNT(*) INTO ret FROM users WHERE user = username AND MD5(pass) = password;
RETURN ret;
END//
DELIMITER ;

La aplicación web como usuario web tiene EXECUTE privilegio, pero no tiene SELECT/INSERT/DELETE privilegios en la tabla users . Por lo tanto, no puede enumerar usuarios ni restablecer todas las contraseñas de una sola vez,

Incluso es posible (pero no muy útil, ya que la capacidad de cargar scripts ejecutables es un escenario ideal para el hombre en el medio) para usar la cuenta guest para recuperar credenciales de acceso web , almacenadas en la tabla users , siempre que el usuario web tenga la contraseña correcta:

  1. el usuario John inicia sesión con la contraseña 'Doe'. La aplicación web se ejecuta como invitado
  2. la función get_credentials('John','Doe') devuelve 'web: myfirstpass'
  3. La aplicación web cambia las credenciales a web y ahora tiene acceso a más funciones

Todo el registro de datos es solo INSERT (solo el administrador puede eliminar registros), y el acceso a datos importantes / "financieros" (por ejemplo, una tabla invoice ) se puede realizar ejecutando todas las operaciones en una tabla temporal de propiedad por web , mientras que se puede usar un procedimiento privilegiado para finalizar y validar la tabla, y copiarla en invoices .

Con un poco más de trabajo, el usuario puede asociarse con una cadena de "identificador de seguridad" altamente aleatoria que es única para él. Solo al proporcionar ese identificador de seguridad se puede acceder a los procedimientos que recuperan las facturas; y esos procedimientos solo seleccionarán facturas con ese mismo identificador.

De esta manera, de manera muy laboriosa, es cierto que un atacante solo puede acceder a los datos de aquellos usuarios que inician sesión, y son engañados de sus credenciales, en el servidor web comprometido.

Te queda el problema de reaccionar rápidamente ante un compromiso de este tipo.

En un servidor Linux con inotify , sería posible para monitorear continuamente los archivos y eliminar aquellos que no están "aprobados" (es decir, su hash SHA1 no se encuentra en la lista de "permitidos"). Cualquier modificación o adición a los archivos monitoreados provocaría su eliminación, así como una alerta que se envía al administrador:

inotify: '/srv/www/padma/htdocs/ CREATE dfqjkw.php'
inotify: '/srv/www/padma/htdocs/ MODIFY dfqjkw.php'
inotify: '/srv/www/padma/htdocs/ CLOSE_WRITE,CLOSE dfqjkw.php'
ANOMALY: '/srv/www/padma/htdocs/dfqjkw.php' (SHA: e0a6bf9020320dca178cf115da4fa26de0278a25cf41702d667988877cdbc2d1) is neither known nor in testing
inotify: '/srv/www/padma/htdocs/ DELETE dfqjkw.php'
ACTIONS: '/srv/www/padma/htdocs/dfqjkw.php' targzipped, sent to root, and removed

Esto también requeriría un poco de ajuste para las personas que suben sus sitios web. Necesitaría un sitio web FTP de "prueba" donde se realiza la carga, y un procedimiento de "aprobación" mediante el cual se extrae la firma de cada archivo y el sitio web se copia en el sistema de archivos de "producción", duplicando efectivamente el uso de datos.

Por otra parte, robar las credenciales de FTP como lo hacen muchos malware troyanos ya no sería útil: al no contar con el procedimiento de aprobación, los archivos comprometidos solo estarán presentes en enlace , que solo sería accesible desde algunas redes seleccionadas, no en enlace que está permitido para todos.

    
respondido por el LSerni 21.05.2013 - 20:53
fuente
1

Usted podría hacer que un sitio web interno solo fuera accesible para localhost que pasara las credenciales al script PHP principal y, por lo tanto, el archivo sería inaccesible para el contexto del usuario del sitio principal y solo se almacenaría en la memoria, pero probablemente eso sea excesivo para la mayoría propósitos.

Si coloca la configuración en un archivo al que no se puede acceder directamente desde la web y limita las conexiones a ser solo desde el servidor web, está bastante protegido, ya que tendrían que secuestrar el servidor web para ejecutar ataques. que las Inyecciones de SQL (y si pueden inyectarse de SQL, podrán acceder a las mismas credenciales que el sitio utiliza legítimamente).

    
respondido por el AJ Henderson 21.05.2013 - 17:22
fuente

Lea otras preguntas en las etiquetas