3 façons de créer un système de gestion de session sécurisé en PHP et MySQL

Table des matières:

3 façons de créer un système de gestion de session sécurisé en PHP et MySQL
3 façons de créer un système de gestion de session sécurisé en PHP et MySQL

Vidéo: 3 façons de créer un système de gestion de session sécurisé en PHP et MySQL

Vidéo: 3 façons de créer un système de gestion de session sécurisé en PHP et MySQL
Vidéo: 7 habitudes qui changeront votre vie de développeur ! 2024, Avril
Anonim

Ce guide vous montrera comment vous pouvez stocker vos sessions en toute sécurité dans une base de données mySQL. Nous crypterons également toutes les données de session qui entrent dans la base de données, ce qui signifie que si quelqu'un parvient à pirater la base de données, toutes les données de session sont cryptées par cryptage AES 256 bits.

Pas

Méthode 1 sur 3: Configurer la base de données mySQL

2238751 1
2238751 1

Étape 1. Créez une base de données MySQL

Dans ce guide, nous allons créer une base de données appelée "secure_sessions".

Découvrez comment créer une base de données dans phpMyAdmin.

Ou vous pouvez utiliser le code SQL ci-dessous pour en créer un pour vous.

Créer un code de base de données:

CRÉER LA BASE DE DONNÉES `secure_sessions`;

Remarque: certains services d'hébergement ne vous permettent pas de créer une base de données via phpMyAdmin, découvrez comment le faire dans cPanel.

2238751 2
2238751 2

Étape 2. Créez un utilisateur avec uniquement les privilèges SELECT, INSERT et DELETE

Cela signifie que s'il y avait une faille de sécurité dans notre script, le pirate ne pourrait pas supprimer les tables de notre base de données. Si vous êtes vraiment paranoïaque, créez un utilisateur différent pour chaque fonction.

  • Utilisateur:

    "sec_utilisateur"

  • Mot de passe:

    "eKcGZr59zAa2BEWU"

Créer un code utilisateur:

CRÉER UN UTILISATEUR 'sec_user'@'localhost' IDENTIFIÉ PAR 'eKcGZr59zAa2BEWU'; GRANT SELECT, INSERT, UPDATE, DELETE ON `secure_sessions`.* TO 'sec_user'@'localhost';

Remarque: il est conseillé de modifier le mot de passe dans le code ci-dessus lors de l'exécution sur votre propre serveur. (Assurez-vous de modifier également votre code PHP.) N'oubliez pas qu'il n'est pas nécessaire que ce soit un mot de passe dont vous vous souviendrez, alors rendez-le aussi compliqué que possible. Voici un générateur de mot de passe aléatoire.

2238751 3
2238751 3

Étape 3. Créez une table MySQL nommée "sessions"

Le code ci-dessous crée une table avec 4 champs (id, set_time, data, session_key).

Créez la table « sessions »:

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;

Nous utilisons le type de données CHAR pour les champs dont nous connaissons la longueur, car les champs "id" et "session_key" auront toujours 128 caractères. L'utilisation de CHAR ici permet d'économiser de la puissance de traitement.

Méthode 2 sur 3: Créer un fichier session.class.php

2238751 4
2238751 4

Étape 1. Créez la classe

Pour commencer un nouveau cours, vous devrez entrer le code ci-dessous:

Nouvelle classe:

séance de classe {

2238751 5
2238751 5

Étape 2. Créez la fonction _construct

Cette fonction sera appelée à chaque fois que nous créons une nouvelle instance d'un objet en utilisant la classe 'session'. Vous pouvez en savoir plus sur la fonction PHP _construct ici.

Cette fonction définit notre gestionnaire de session personnalisé afin qu'il soit disponible pour une utilisation dès que la classe est instanciée (c'est-à-dire, faite/construite/construite).

Fonction _construct:

function _construct() { // définit nos fonctions de session personnalisées. session_set_save_handler(array($this, 'open'), array($this, 'close'), array($this, 'read'), array($this, 'write'), array($this, 'destroy'), array($this, 'gc')); // Cette ligne empêche les effets inattendus lors de l'utilisation d'objets comme gestionnaires de sauvegarde. register_shutdown_function('session_write_close'); }

2238751 6
2238751 6

Étape 3. Créez la fonction start_session

Cette fonction sera appelée à chaque fois que vous voudrez démarrer une nouvelle session, utilisez-la à la place de session_start();. Voir les commentaires dans le code pour voir ce que fait chaque ligne.

fonction start_session:

function start_session($session_name, $secure) { // Assurez-vous que le cookie de session n'est pas accessible via javascript. $httponly = vrai; // Algorithme de hachage à utiliser pour la session. (utilisez hash_algos() pour obtenir une liste des hachages disponibles.) $session_hash = 'sha512'; // Vérifie si le hachage est disponible if (in_array($session_hash, hash_algos())) { // Définit la fonction has. ini_set('session.hash_function', $session_hash); } // Combien de bits par caractère du hachage. // Les valeurs possibles sont '4' (0-9, a-f), '5' (0-9, a-v) et '6' (0-9, a-z, A-Z, "-", ", "). ini_set('session.hash_bits_per_character', 5); // Force la session à n'utiliser que des cookies, pas des variables URL. ini_set('session.use_only_cookies', 1); // Récupère les paramètres du cookie de session $cookieParams = session_get_cookie_params(); // Définir les paramètres session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly); // Changer le nom de la session session_name($session_name); // Maintenant, nous démarrons la session session_start(); // Cette ligne régénère la session et supprime l'ancienne. // Il génère également une nouvelle clé de cryptage dans la base de données. session_regenerate_id(true); }

2238751 7
2238751 7

Étape 4. Créez une fonction ouverte

Cette fonction sera appelée par les sessions PHP lorsque nous démarrons une nouvelle session, nous l'utilisons pour démarrer une nouvelle connexion à la base de données.

fonction ouverte:

function open() { $host = 'localhost'; $user = 'sec_user'; $passer = 'eKcGZr59zAa2BEWU'; $name = 'secure_sessions'; $mysqli = new mysqli($host, $user, $pass, $name); $this->db = $mysqli; renvoie vrai; }

2238751 8
2238751 8

Étape 5. Créez une fonction de fermeture

Cette fonction sera appelée lorsque les sessions voudront être fermées.

fonction de fermeture:

function close() { $this->db->close(); renvoie vrai; }

2238751 9
2238751 9

Étape 6. Créez une fonction de lecture

Cette fonction sera appelée par PHP lorsque nous essaierons d'accéder à une session par exemple lorsque nous utilisons echo $_SESSION['something'];. Comme il peut y avoir de nombreux appels à cette fonction sur une seule page, nous tirons parti des instructions préparées, non seulement pour la sécurité mais aussi pour les performances. Nous ne préparons l'instruction qu'une seule fois, puis nous pouvons l'exécuter plusieurs fois.

Nous décryptons également les données de session qui sont cryptées dans la base de données. Nous utilisons un cryptage AES 256 bits dans nos sessions.

fonction de lecture:

function read($id) { if(!isset($this->read_stmt)) { $this->read_stmt = $this->db->prepare("SELECT data FROM sessions 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(); $key = $this->getkey($id); $data = $this->decrypt($data, $key); renvoie $données; }

2238751 10
2238751 10

Étape 7. Créez une fonction d'écriture

Cette fonction est utilisée lorsque nous affectons une valeur à une session, par exemple $_SESSION['something'] = 'something else';. La fonction crypte toutes les données qui sont insérées dans la base de données.

fonction d'écriture:

function write($id, $data) { // Obtenir une clé unique $key = $this->getkey($id); // Crypter les données $data = $this->encrypt($data, $key); $heure = heure(); if(!isset($this->w_stmt)) { $this->w_stmt = $this->db->prepare("REPLACE INTO sessions (id, set_time, data, session_key) VALEURS (?, ?, ?, ?)"); } $this->w_stmt->bind_param('siss', $id, $time, $data, $key); $this->w_stmt->execute(); renvoie vrai; }

2238751 11
2238751 11

Étape 8. Créez la fonction de destruction

Cette fonction supprime la session de la base de données, elle est utilisée par php lorsque nous appelons des fonctions comme session_destroy();.

fonction de destruction:

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

2238751 12
2238751 12

Étape 9. Créez la fonction gc (collecteur de déchets)

Cette fonction est la fonction de ramasse-miettes, elle est appelée pour supprimer les anciennes sessions. La fréquence à laquelle cette fonction est appelée est déterminée par deux directives de configuration, session.gc_probability et session.gc_divisor.

fonction gc():

function gc($max) { if(!isset($this->gc_stmt)) { $this->gc_stmt = $this->db->prepare("DELETE FROM sessions WHERE set_time < ?"); } $ancien = heure() - $max; $this->gc_stmt->bind_param('s', $old); $this->gc_stmt->execute(); renvoie vrai; }

2238751 13
2238751 13

Étape 10. Créez la fonction getKey

Cette fonction permet d'obtenir la clé unique de chiffrement de la table des sessions. S'il n'y a pas de session, il renvoie simplement une nouvelle clé aléatoire pour le cryptage.

getkey() Fonction:

fonction privée getkey($id) { if(!isset($this->key_stmt)) { $this->key_stmt = $this->db->prepare("SELECT session_key FROM sessions 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(); renvoie $key; } else { $random_key = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true)); renvoie $random_key; } }

2238751 14
2238751 14

Étape 11. Créez des fonctions de chiffrement et de déchiffrement

Ces fonctions cryptent les données des sessions, elles utilisent une clé de cryptage issue de la base de données qui est différente pour chaque session. Nous n'utilisons pas directement cette clé dans le cryptage, mais nous l'utilisons pour rendre le hachage de clé encore plus aléatoire.

Fonctions encrypt() et decrypt():

private function encrypt($data, $key) { $salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHEGE*ewr4n39=E@rAsp7c-Ph@pH'; $key = substr(hash('sha256', $salt.$key.$salt), 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)); renvoie $crypté; } fonction privée decrypt($data, $key) { $salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHEGE*ewr4n39=E@rAsp7c-Ph@pH'; $key = substr(hash('sha256', $salt.$key.$salt), 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); $déchiffré = rtrim($déchiffré, "\0"); renvoie $déchiffré; }

2238751 15
2238751 15

Étape 12. Fin de la classe

Ici, nous terminons simplement les classes accolades:

Classe de fin:

}

Méthode 3 sur 3: Création de pages avec des sessions

2238751 16
2238751 16

Étape 1. Utilisation des sessions avec le gestionnaire de sessions personnalisé

Voici comment démarrer une nouvelle session; vous devrez l'inclure sur chaque page sur laquelle vous souhaitez accéder aux sessions, utilisez-le au lieu de session_start();

Commencer une session:

require('session.class.php'); $session = nouvelle session(); // Définir sur true si vous utilisez https $session->start_session('_s', false); $_SESSION['quelque chose'] = 'Une valeur.'; echo $_SESSION['quelque chose'];

Conseillé: