3 formas de crear un sistema de gestión de sesiones seguro en PHP y MySQL

Tabla de contenido:

3 formas de crear un sistema de gestión de sesiones seguro en PHP y MySQL
3 formas de crear un sistema de gestión de sesiones seguro en PHP y MySQL

Video: 3 formas de crear un sistema de gestión de sesiones seguro en PHP y MySQL

Video: 3 formas de crear un sistema de gestión de sesiones seguro en PHP y MySQL
Video: La Vida de un PROGRAMADOR WEB (Cómo ser un Desarrollador Web, Con qué lenguaje empezar) 2024, Abril
Anonim

Esta guía le mostrará cómo puede almacenar sus sesiones de forma segura en una base de datos mySQL. También encriptaremos todos los datos de la sesión que van a la base de datos, lo que significa que si alguien logra piratear la base de datos, todos los datos de la sesión se encriptan mediante encriptación AES de 256 bits.

Pasos

Método 1 de 3: configurar la base de datos mySQL

2238751 1
2238751 1

Paso 1. Cree una base de datos MySQL

En esta guía crearemos una base de datos llamada "secure_sessions".

Vea cómo crear una base de datos en phpMyAdmin.

O puede usar el código SQL a continuación para crear uno para usted.

Crear código de base de datos:

CREAR BASE DE DATOS `Secure_sessions`;

Nota: Algunos servicios de alojamiento no le permiten crear una base de datos a través de phpMyAdmin. Aprenda cómo hacerlo en cPanel.

2238751 2
2238751 2

Paso 2. Cree un usuario con privilegios SELECT, INSERT y DELETE únicamente

Esto significa que si alguna vez hubo una violación de seguridad en nuestro script, el pirata informático no podría eliminar tablas de nuestra base de datos. Si está realmente paranoico, cree un usuario diferente para cada función.

  • Usuario:

    "sec_user"

  • Contraseña:

    "eKcGZr59zAa2BEWU"

Crear código de usuario:

CREAR USUARIO 'sec_user' @ 'localhost' IDENTIFICADO POR 'eKcGZr59zAa2BEWU'; GRANT SELECT, INSERT, UPDATE, DELETE ON `secure_sessions`. * TO 'sec_user' @ 'localhost';

Nota: es una buena idea cambiar la contraseña en el código anterior cuando se ejecuta en su propio servidor. (Asegúrese de cambiar también su código PHP). Recuerde que no es necesario que sea una contraseña que pueda recordar, por lo que la creación es lo más complicada posible. Aquí hay un generador de contraseñas al azar.

2238751 3
2238751 3

Paso 3. Cree una tabla MySQL llamada "sesiones"

El siguiente código crea una tabla con 4 campos (id, set_time, data, session_key).

Crea la tabla de "sesiones":

CREATE TABLE `sesiones` (` id` char (128) NOT NULL, `set_time` char (10) NOT NULL,` data` text NOT NULL, `session_key` char (128) NOT NULL, PRIMARY KEY (` id`)) MOTOR = JUEGO DE CARTOS POR DEFECTO InnoDB = latin1;

Usamos el tipo de datos CHAR para los campos cuya longitud conocemos, ya que los campos "id" y "session_key" siempre tendrán 128 caracteres. El uso de CHAR aquí ahorra potencia de procesamiento.

Método 2 de 3: crear archivo session.class.php

2238751 4
2238751 4

Paso 1. Crear clase

Para comenzar una nueva clase, deberá ingresar el siguiente código:

Nueva clase:

sesión de clase {

2238751 5
2238751 5

Paso 2. Cree la función _construct

Esta función será llamada cada vez que creamos una nueva instancia de un objeto usando la clase 'sesión'. Puede leer sobre la función PHP _construct aquí.

Esta función establece nuestro controlador de sesión personalizado para que esté disponible para su uso tan pronto como se instancia la clase (es decir, hecha / construida / construida).

_construct función:

function _construct () {// establece nuestras funciones de sesión personalizadas. session_set_save_handler (matriz ($ esto, 'abrir'), matriz ($ esto, 'cerrar'), matriz ($ esto, 'leer'), matriz ($ esto, 'escribir'), matriz ($ esto, 'destruir'), matriz ($ this, 'gc')); // Esta línea evita efectos inesperados al usar objetos como manejadores de salvar. register_shutdown_function ('session_write_close'); }

2238751 6
2238751 6

Paso 3. Cree la función start_session

Esta función se llamará cada vez que desee iniciar una nueva sesión, úsela en lugar de session_start ();. Vea los comentarios en el código para ver qué hace cada línea.

función start_session:

function start_session ($ session_name, $ secure) {// Asegúrese de que la cookie de sesión no sea accesible a través de javascript. $ httponly = verdadero; // Algoritmo hash a utilizar para la sesión. (use hash_algos () para obtener una lista de hashes disponibles.) $ session_hash = 'sha512'; // Verifica si el hash está disponible if (in_array ($ session_hash, hash_algos ())) {// Establece la función has. ini_set ('session.hash_function', $ session_hash); } // Cuántos bits por carácter del hash. // Los valores posibles son '4' (0-9, a-f), '5' (0-9, a-v) y '6' (0-9, a-z, A-Z, "-", ","). ini_set ('session.hash_bits_per_character', 5); // Obligar a la sesión a utilizar solo cookies, no variables de URL. ini_set ('session.use_only_cookies', 1); // Obtener los parámetros de la cookie de sesión $ cookieParams = session_get_cookie_params (); // Establecer los parámetros session_set_cookie_params ($ cookieParams ["vida"], $ cookieParams ["ruta"], $ cookieParams ["dominio"], $ seguro, $ httponly); // Cambiar el nombre de la sesión session_name ($ session_name); // Ahora comenzamos la sesión session_start (); // Esta línea regenera la sesión y borra la anterior. // También genera una nueva clave de cifrado en la base de datos. session_regenerate_id (verdadero); }

2238751 7
2238751 7

Paso 4. Cree la función abierta

Esta función será llamada por las sesiones de PHP cuando iniciamos una nueva sesión, la usamos para iniciar una nueva conexión a la base de datos.

función abierta:

función open () {$ host = 'localhost'; $ usuario = 'sec_user'; $ pase = 'eKcGZr59zAa2BEWU'; $ nombre = 'sesiones_seguras'; $ mysqli = new mysqli ($ host, $ usuario, $ pass, $ nombre); $ esto-> db = $ mysqli; devuelve verdadero; }

2238751 8
2238751 8

Paso 5. Cree la función de cierre

Esta función se llamará cuando las sesiones quieran cerrarse.

función de cierre:

función close () {$ this-> db-> close (); devuelve verdadero; }

2238751 9
2238751 9

Paso 6. Cree la función de lectura

PHP llamará a esta función cuando intentemos acceder a una sesión, por ejemplo, cuando usemos echo $ _SESSION ['algo'];. Debido a que puede haber muchas llamadas a esta función en una sola página, aprovechamos las declaraciones preparadas, no solo por seguridad sino también por rendimiento. Solo preparamos la declaración una vez, luego podemos ejecutarla muchas veces.

También desciframos los datos de la sesión que están cifrados en la base de datos. Estamos utilizando cifrado AES de 256 bits en nuestras sesiones.

función de lectura:

function read ($ id) {if (! isset ($ this-> read_stmt)) {$ this-> read_stmt = $ this-> db-> prepare ("SELECCIONAR datos DE sesiones DONDE id =? LIMIT 1"); } $ esto-> read_stmt-> bind_param ('s', $ id); $ esto-> leer_stmt-> ejecutar (); $ esto-> read_stmt-> store_result (); $ this-> read_stmt-> bind_result ($ datos); $ esto-> read_stmt-> fetch (); $ clave = $ esto-> getkey ($ id); $ datos = $ esto-> descifrar ($ datos, $ clave); devolver $ datos; }

2238751 10
2238751 10

Paso 7. Cree la función de escritura

Esta función se usa cuando asignamos un valor a una sesión, por ejemplo $ _SESSION ['algo'] = 'algo más';. La función cifra todos los datos que se insertan en la base de datos.

función de escritura:

function write ($ id, $ data) {// Obtener clave única $ key = $ this-> getkey ($ id); // Encriptar los datos $ data = $ this-> encrypt ($ data, $ key); $ tiempo = tiempo (); if (! isset ($ this-> w_stmt)) {$ this-> w_stmt = $ this-> db-> prepare ("REEMPLAZAR EN sesiones (id, set_time, data, session_key) VALORES (?,?,?,?) "); } $ this-> w_stmt-> bind_param ('siss', $ id, $ time, $ data, $ key); $ esto-> w_stmt-> ejecutar (); devuelve verdadero; }

2238751 11
2238751 11

Paso 8. Cree la función de destrucción

Esta función elimina la sesión de la base de datos, es utilizada por php cuando llamamos a funciones como session_destroy ();.

función de destrucción:

function destroy ($ id) {if (! isset ($ this-> delete_stmt)) {$ this-> delete_stmt = $ this-> db-> prepare ("ELIMINAR DE las sesiones DONDE id =?"); } $ this-> delete_stmt-> bind_param ('s', $ id); $ esto-> eliminar_stmt-> ejecutar (); devuelve verdadero; }

2238751 12
2238751 12

Paso 9. Cree la función gc (recolector de basura)

Esta función es la función del recolector de basura a la que se llama para eliminar sesiones antiguas. La frecuencia con la que se llama a esta función está determinada por dos directivas de configuración, session.gc_probability y session.gc_divisor.

Función gc ():

function gc ($ max) {if (! isset ($ this-> gc_stmt)) {$ this-> gc_stmt = $ this-> db-> prepare ("ELIMINAR DE las sesiones DONDE set_time <?"); } $ antiguo = tiempo () - $ max; $ esto-> gc_stmt-> bind_param ('s', $ antiguo); $ esto-> gc_stmt-> ejecutar (); devuelve verdadero; }

2238751 13
2238751 13

Paso 10. Cree la función getKey

Esta función se utiliza para obtener la clave única para el cifrado de la tabla de sesiones. Si no hay sesión, simplemente devuelve una nueva clave aleatoria para el cifrado.

Función getkey ():

función privada getkey ($ id) {if (! isset ($ this-> key_stmt)) {$ this-> key_stmt = $ this-> db-> prepare ("SELECCIONAR session_key FROM sesiones DONDE id =? LIMIT 1"); } $ esto-> key_stmt-> bind_param ('s', $ id); $ esto-> key_stmt-> ejecutar (); $ esto-> key_stmt-> store_result (); if ($ esto-> key_stmt-> num_rows == 1) {$ this-> key_stmt-> bind_result ($ clave); $ esto-> key_stmt-> fetch (); return $ clave; } else {$ clave_aleatoria = hash ('sha512', uniqid (mt_rand (1, mt_getrandmax ()), verdadero)); return $ clave_aleatoria; }}

2238751 14
2238751 14

Paso 11. Cree funciones de cifrado y descifrado

Estas funciones cifran los datos de las sesiones, utilizan una clave de cifrado de la base de datos que es diferente para cada sesión. No usamos directamente esa clave en el cifrado, pero la usamos para hacer que el hash de la clave sea aún más aleatorio.

Funciones encriptar () y desencriptar ():

función privada encriptar ($ datos, $ clave) {$ salt = 'cH! swe! retReGu7W6bEDRup7usuDUh9THeD2CHeGE * ewr4n39 = E @ rAsp7c-Ph @ pH'; $ clave = substr (hash ('sha256', $ sal. $ clave. $ sal), 0, 32); $ iv_size = mcrypt_get_iv_size (MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $ iv = mcrypt_create_iv ($ tamaño_iv, MCRYPT_RAND); $ encriptado = base64_encode (mcrypt_encrypt (MCRYPT_RIJNDAEL_256, $ clave, $ datos, MCRYPT_MODE_ECB, $ iv)); devolver $ cifrado; } función privada descifrar ($ datos, $ clave) {$ salt = 'cH! swe! retReGu7W6bEDRup7usuDUh9THeD2CHeGE * ewr4n39 = E @ rAsp7c-Ph @ pH'; $ clave = substr (hash ('sha256', $ sal. $ clave. $ sal), 0, 32); $ iv_size = mcrypt_get_iv_size (MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $ iv = mcrypt_create_iv ($ tamaño_iv, MCRYPT_RAND); $ descifrado = mcrypt_decrypt (MCRYPT_RIJNDAEL_256, $ clave, base64_decode ($ datos), MCRYPT_MODE_ECB, $ iv); $ descifrado = rtrim ($ descifrado, "\ 0"); return $ descifrado; }

2238751 15
2238751 15

Paso 12. Fin de la clase

Aquí acabamos de terminar las clases con llaves:

Clase final:

}

Método 3 de 3: creación de páginas con sesiones

2238751 16
2238751 16

Paso 1. Usar sesiones con el administrador de sesiones personalizado

A continuación se muestra cómo iniciaría una nueva sesión; Debería incluir esto en cada página en la que desee acceder a las sesiones, utilícelo en lugar de session_start ();

Iniciar una sesión:

require ('session.class.php'); $ sesión = nueva sesión (); // Establecer en verdadero si usa https $ sesión-> start_session ('_ s', falso); $ _SESSION ['algo'] = 'Un valor.'; echo $ _SESSION ['algo'];

Recomendado: