56 lines
1.5 KiB
PHP
56 lines
1.5 KiB
PHP
|
|
<?php
|
||
|
|
/**
|
||
|
|
* CSRF Protection Middleware
|
||
|
|
* Generates and validates CSRF tokens for all state-changing operations
|
||
|
|
*/
|
||
|
|
class CsrfMiddleware {
|
||
|
|
private static $tokenName = 'csrf_token';
|
||
|
|
private static $tokenTime = 'csrf_token_time';
|
||
|
|
private static $tokenLifetime = 3600; // 1 hour
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generate a new CSRF token
|
||
|
|
*/
|
||
|
|
public static function generateToken() {
|
||
|
|
$_SESSION[self::$tokenName] = bin2hex(random_bytes(32));
|
||
|
|
$_SESSION[self::$tokenTime] = time();
|
||
|
|
return $_SESSION[self::$tokenName];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get current CSRF token, regenerate if expired
|
||
|
|
*/
|
||
|
|
public static function getToken() {
|
||
|
|
if (!isset($_SESSION[self::$tokenName]) || self::isTokenExpired()) {
|
||
|
|
return self::generateToken();
|
||
|
|
}
|
||
|
|
return $_SESSION[self::$tokenName];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Validate CSRF token (constant-time comparison)
|
||
|
|
*/
|
||
|
|
public static function validateToken($token) {
|
||
|
|
if (!isset($_SESSION[self::$tokenName])) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (self::isTokenExpired()) {
|
||
|
|
self::generateToken(); // Auto-regenerate expired token
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Constant-time comparison to prevent timing attacks
|
||
|
|
return hash_equals($_SESSION[self::$tokenName], $token);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if token is expired
|
||
|
|
*/
|
||
|
|
private static function isTokenExpired() {
|
||
|
|
return !isset($_SESSION[self::$tokenTime]) ||
|
||
|
|
(time() - $_SESSION[self::$tokenTime]) > self::$tokenLifetime;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
?>
|