3 modi per creare un sistema di gestione delle sessioni sicuro in PHP e MySQL

Sommario:

3 modi per creare un sistema di gestione delle sessioni sicuro in PHP e MySQL
3 modi per creare un sistema di gestione delle sessioni sicuro in PHP e MySQL

Video: 3 modi per creare un sistema di gestione delle sessioni sicuro in PHP e MySQL

Video: 3 modi per creare un sistema di gestione delle sessioni sicuro in PHP e MySQL
Video: Come si diventa programmatore da autodidatta? 2024, Aprile
Anonim

Questa guida ti mostrerà come archiviare le tue sessioni in modo sicuro in un database mySQL. Crittograferemo anche tutti i dati della sessione che entrano nel database, il che significa che se qualcuno riesce a violare il database, tutti i dati della sessione vengono crittografati con la crittografia AES a 256 bit.

Passi

Metodo 1 di 3: Configura database mySQL

2238751 1
2238751 1

Passaggio 1. Creare un database MySQL

In questa guida creeremo un database chiamato "secure_sessions".

Scopri come creare un database in phpMyAdmin.

Oppure puoi utilizzare il codice SQL di seguito per crearne uno per te.

Crea codice database:

CREA DATABASE `secure_sessions`;

Nota: alcuni servizi di hosting non ti consentono di creare un database tramite phpMyAdmin, scopri come farlo in cPanel.

2238751 2
2238751 2

Passaggio 2. Creare un utente con solo i privilegi SELECT, INSERT e DELETE

Ciò significa che se si verificasse una violazione della sicurezza nel nostro script, l'hacker non potrebbe eliminare le tabelle dal nostro database. Se sei davvero paranoico, crea un utente diverso per ogni funzione.

  • Utente:

    "sec_user"

  • Parola d'ordine:

    "eKcGZr59zAa2BEWU"

Crea codice utente:

CREA UTENTE 'sec_user'@'localhost' IDENTIFICATO DA 'eKcGZr59zAa2BEWU'; CONCEDERE SELECT, INSERT, UPDATE, DELETE ON `secure_sessions`.* TO 'sec_user'@'localhost';

Nota: è una buona idea cambiare la password nel codice sopra quando è in esecuzione sul proprio server. (Assicurati di cambiare anche il tuo codice PHP.) Ricorda che non è necessario che sia una password che puoi ricordare, quindi make è il più complicato possibile. Ecco un generatore di password casuali.

2238751 3
2238751 3

Passaggio 3. Creare una tabella MySQL denominata "sessioni"

Il codice seguente crea una tabella con 4 campi (id, set_time, data, session_key).

Crea la tabella "sessioni":

CREATE TABLE `sessions` (`id` char(128) NOT NULL, `set_time` char(10) NOT NULL, `data` text NOT NULL, `session_key` char(128) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Usiamo il tipo di dati CHAR per i campi di cui conosciamo la lunghezza, poiché i campi "id" e "session_key" saranno sempre lunghi 128 caratteri. L'utilizzo di CHAR qui consente di risparmiare sulla potenza di elaborazione.

Metodo 2 di 3: creare il file session.class.php

2238751 4
2238751 4

Passaggio 1. Crea classe

Per iniziare una nuova classe dovrai inserire il codice qui sotto:

Nuova classe:

sessione di classe {

2238751 5
2238751 5

Passaggio 2. Creare la funzione _construct

Questa funzione verrà chiamata ogni volta che creiamo una nuova istanza di un oggetto utilizzando la classe 'session'. Puoi leggere la funzione PHP _construct qui.

Questa funzione imposta il nostro gestore di sessione personalizzato in modo che sia disponibile per l'uso non appena viene istanziata la classe (ad esempio, realizzata/costruita/costruita).

_funzione di costruzione:

function _construct() { // imposta le nostre funzioni di sessione personalizzate. session_set_save_handler(array($this, 'open'), array($this, 'close'), array($this, 'read'), array($this, 'write'), array($this, 'destroy'), array($questo, 'gc')); // Questa riga previene effetti imprevisti quando si utilizzano oggetti come gestori di salvataggio. register_shutdown_function('session_write_close'); }

2238751 6
2238751 6

Passaggio 3. Creare la funzione start_session

Questa funzione verrà chiamata ogni volta che vorrai avviare una nuova sessione, usala al posto di session_start();. Vedere i commenti nel codice per vedere cosa fa ogni riga.

funzione start_session:

function start_session($session_name, $secure) { // Assicurati che il cookie di sessione non sia accessibile tramite javascript. $httpsolo = vero; // Algoritmo hash da utilizzare per la sessione. (usa hash_algos() per ottenere un elenco di hash disponibili.) $session_hash = 'sha512'; // Controlla se hash è disponibile if (in_array($session_hash, hash_algos())) { // Imposta la funzione has. ini_set('session.hash_function', $session_hash); } // Quanti bit per carattere dell'hash. // I valori possibili sono '4' (0-9, a-f), '5' (0-9, a-v) e '6' (0-9, a-z, A-Z, "-", ", "). ini_set('session.hash_bits_per_character', 5); // Forza la sessione a utilizzare solo i cookie, non le variabili URL. ini_set('session.use_only_cookies', 1); // Ottieni i parametri del cookie di sessione $cookieParams = session_get_cookie_params(); // Imposta i parametri session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly); // Cambia il nome della sessione session_name($session_name); // Ora avviamo la sessione session_start(); // Questa riga rigenera la sessione ed elimina quella vecchia. // Genera anche una nuova chiave di crittografia nel database. session_regenerate_id(true); }

2238751 7
2238751 7

Passaggio 4. Creare una funzione aperta

Questa funzione verrà chiamata dalle sessioni PHP quando avviamo una nuova sessione, la usiamo per avviare una nuova connessione al database.

funzione aperta:

funzione open() { $host = 'localhost'; $user = 'sec_user'; $pass = 'eKcGZr59zAa2BEWU'; $name = 'secure_sessions'; $mysqli = new mysqli($host, $user, $pass, $name); $questo->db = $mysqli; restituire vero; }

2238751 8
2238751 8

Passaggio 5. Creare la funzione di chiusura

Questa funzione verrà chiamata quando le sessioni vorranno essere chiuse.

funzione di chiusura:

funzione close() { $this->db->close(); restituire vero; }

2238751 9
2238751 9

Passaggio 6. Creare la funzione di lettura

Questa funzione verrà chiamata da PHP quando proveremo ad accedere a una sessione, ad esempio quando usiamo echo $_SESSION['qualcosa'];. Poiché potrebbero esserci molte chiamate a questa funzione su una singola pagina, sfruttiamo le istruzioni preparate, non solo per la sicurezza ma anche per le prestazioni. Prepariamo l'istruzione solo una volta, quindi possiamo eseguirla molte volte.

Decrittografiamo anche i dati della sessione che sono crittografati nel database. Utilizziamo la crittografia AES a 256 bit nelle nostre sessioni.

funzione di lettura:

function read($id) { if(!isset($this->read_stmt)) { $this->read_stmt = $this->db->prepare("SELECT data FROM session WHERE id = ? LIMIT 1"); } $this->read_stmt->bind_param('s', $id); $this->read_stmt->execute(); $this->read_stmt->store_result(); $this->read_stmt->bind_result($data); $this->read_stmt->fetch(); $chiave = $questo->getkey($id); $data = $this->decrypt($data, $key); restituisce $dati; }

2238751 10
2238751 10

Passaggio 7. Creare la funzione di scrittura

Questa funzione viene utilizzata quando assegniamo un valore a una sessione, ad esempio $_SESSION['qualcosa'] = 'qualcos'altro';. La funzione crittografa tutti i dati che vengono inseriti nel database.

funzione di scrittura:

function write($id, $data) { // Ottieni una chiave univoca $key = $this->getkey($id); // Cripta i dati $data = $this->encrypt($data, $key); $tempo = tempo(); if(!isset($this->w_stmt)) { $this->w_stmt = $this->db->prepare("REPLACE INTO session (id, set_time, data, session_key) VALUES (?, ?, ?, ?)"); } $this->w_stmt->bind_param('siss', $id, $time, $data, $key); $this->w_stmt->execute(); restituire vero; }

2238751 11
2238751 11

Passaggio 8. Creare la funzione di distruzione

Questa funzione cancella la sessione dal database, è usata da php quando chiamiamo funzioni come session_destroy();.

funzione di distruzione:

function destroy($id) { if(!isset($this->delete_stmt)) { $this->delete_stmt = $this->db->prepare("DELETE FROM sessioni WHERE id = ?"); } $this->delete_stmt->bind_param('s', $id); $this->delete_stmt->execute(); restituire vero; }

2238751 12
2238751 12

Passaggio 9. Creare la funzione gc (garbage collector)

Questa funzione è la funzione di garbage collector che viene chiamata per eliminare le vecchie sessioni. La frequenza con cui viene chiamata questa funzione è determinata da due direttive di configurazione, session.gc_probability e session.gc_divisor.

gc() funzione:

function gc($max) { if(!isset($this->gc_stmt)) { $this->gc_stmt = $this->db->prepare("DELETE FROM sessioni WHERE set_time < ?"); } $vecchio = tempo() - $max; $this->gc_stmt->bind_param('s', $old); $this->gc_stmt->execute(); restituire vero; }

2238751 13
2238751 13

Passaggio 10. Crea la funzione getKey

Questa funzione viene utilizzata per ottenere la chiave univoca per la crittografia dalla tabella delle sessioni. Se non è presente alcuna sessione, restituisce solo una nuova chiave casuale per la crittografia.

getkey() Funzione:

private function getkey($id) { if(!isset($this->key_stmt)) { $this->key_stmt = $this->db->prepare("SELECT session_key FROM sessioni WHERE id = ? LIMIT 1"); } $this->key_stmt->bind_param('s', $id); $this->key_stmt->execute(); $this->key_stmt->store_result(); if($this->key_stmt->num_rows == 1) { $this->key_stmt->bind_result($key); $this->key_stmt->fetch(); restituisce $chiave; } else { $chiave_casuale = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true)); return $chiave_casuale; } }

2238751 14
2238751 14

Passaggio 11. Creare funzioni di crittografia e decrittografia

Queste funzioni crittografano i dati delle sessioni, utilizzano una chiave di crittografia del database che è diversa per ogni sessione. Non usiamo direttamente quella chiave nella crittografia, ma la usiamo per rendere l'hash della chiave ancora più casuale.

funzioni encrypt() e decrypt():

private function encrypt($data, $key) { $salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHeGE*ewr4n39=E@rAsp7c-Ph@pH'; $chiave = substr(hash('sha256', $sale.$chiave.$sale), 0, 32); $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_ECB, $iv)); restituisce $ crittografato; } private function decrypt($data, $key) { $salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHeGE*ewr4n39=E@rAsp7c-Ph@pH'; $chiave = substr(hash('sha256', $sale.$chiave.$sale), 0, 32); $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($data), MCRYPT_MODE_ECB, $iv); $decrittografato = rtrim($decrittografato, "\0"); restituisce $ decifrato; }

2238751 15
2238751 15

Passaggio 12. Fine della lezione

Qui finiamo solo le parentesi graffe delle classi:

Fine classe:

}

Metodo 3 di 3: creazione di pagine con sessioni

2238751 16
2238751 16

Passaggio 1. Utilizzo delle sessioni con il gestore sessioni personalizzato

Di seguito è riportato come inizieresti una nuova sessione; dovresti includerlo in ogni pagina a cui vuoi accedere alle sessioni, usalo al posto di session_start();

Avvio di una sessione:

require('session.class.php'); $sessione = nuova sessione(); // Imposta su vero se si utilizza https $session->start_session('_s', false); $_SESSION['qualcosa'] = 'Un valore.'; echo $_SESSION['qualcosa'];

Consigliato: