This commit is contained in:
KANE LAZENI 2026-04-18 22:02:15 +00:00
parent 8949fbf40f
commit dfce322094
2 changed files with 20 additions and 34 deletions

View File

@ -1,57 +1,43 @@
<?php <?php
class Csrf class Csrf
{ {
/** /**
* Génère et stocke un token CSRF en session * Génère UN seul token pour toute la session
*/ */
public static function generateToken(string $formName = 'default'): string { public static function generateToken(): string {
if (empty($_SESSION['csrf_tokens'][$formName])) { if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_tokens'][$formName] = [ $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
'token' => bin2hex(random_bytes(32)),
'created_at' => time(),
];
} }
return $_SESSION['csrf_tokens'][$formName]['token']; return $_SESSION['csrf_token'];
} }
/** /**
* Valide le token soumis * Valide le token soumis
*/ */
public static function validateToken(string $submittedToken, string $formName = 'default'): bool { public static function validateToken(string $submittedToken): bool {
$session = $_SESSION['csrf_tokens'][$formName] ?? null; $sessionToken = $_SESSION['csrf_token'] ?? '';
if (!$session) return false; if (empty($sessionToken)) return false;
// Expiration après 1 heure // ✅ hash_equals évite les attaques par timing
if (time() - $session['created_at'] > 3600) { return hash_equals($sessionToken, $submittedToken);
self::destroyToken($formName);
return false;
}
$valid = hash_equals($session['token'], $submittedToken); // ⚠️ On NE supprime PAS le token ici (réutilisable)
// Token à usage unique : on le supprime après validation
if ($valid) {
self::destroyToken($formName);
}
return $valid;
} }
/** /**
* Supprime un token * Champ HTML à insérer dans les formulaires
*/ */
public static function destroyToken(string $formName = 'default'): void { public static function field(): string {
unset($_SESSION['csrf_tokens'][$formName]); $token = self::generateToken();
return '<input type="hidden" name="csrf_token" value="' . htmlspecialchars($token) . '">';
} }
/** /**
* Retourne le champ HTML caché à insérer dans les formulaires * Régénère le token (à appeler à la déconnexion)
*/ */
public static function field(string $formName = 'default'): string { public static function regenerate(): void {
$token = self::generateToken($formName); $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
return '<input type="hidden" name="csrf_token" value="' . htmlspecialchars($token) . '">'
. '<input type="hidden" name="csrf_form" value="' . htmlspecialchars($formName) . '">';
} }
} }

View File

@ -94,7 +94,7 @@ class Vue
ob_start(); ob_start();
require $fichier; require $fichier;
// 18/04/2026 => genérer // 18/04/2026 => genérer
Csrf::field($fichier); Csrf::field();
return ob_get_clean(); return ob_get_clean();
} }
else { else {