Implement CSRF protection for user invitation and management actions; add QR code generation script; secure internal includes directory with .htaccess

This commit is contained in:
2026-09-11 14:46:08 +02:00
parent 55618ffaed
commit cf0ceeca82
18 changed files with 413 additions and 163 deletions
+49
View File
@@ -568,6 +568,55 @@ function verify_csrf_token(?string $token): bool {
return !empty($token) && !empty($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}
/**
* Rate limiting helpers via app_cache
*/
function fociz_check_rate_limit(string $actionKey, int $maxAttempts = 5, int $decaySeconds = 900): array {
require_once __DIR__ . '/cache.php';
$cacheKey = 'rl_' . hash('sha256', $actionKey);
$data = fociz_cache_get($cacheKey);
$attempts = 0;
$expiresAt = time() + $decaySeconds;
if (is_array($data)) {
$attempts = (int)($data['attempts'] ?? 0);
$expiresAt = (int)($data['expires_at'] ?? $expiresAt);
}
$allowed = ($attempts < $maxAttempts);
$remaining = max(0, $maxAttempts - $attempts);
$retryAfter = max(0, $expiresAt - time());
return [
'allowed' => $allowed,
'remaining' => $remaining,
'retry_after' => $retryAfter,
'attempts' => $attempts
];
}
function fociz_hit_rate_limit(string $actionKey, int $decaySeconds = 900): void {
require_once __DIR__ . '/cache.php';
$cacheKey = 'rl_' . hash('sha256', $actionKey);
$data = fociz_cache_get($cacheKey);
$attempts = 1;
$expiresAt = time() + $decaySeconds;
if (is_array($data)) {
$attempts = (int)($data['attempts'] ?? 0) + 1;
$expiresAt = (int)($data['expires_at'] ?? $expiresAt);
}
$ttl = max(1, $expiresAt - time());
fociz_cache_set($cacheKey, ['attempts' => $attempts, 'expires_at' => $expiresAt], $ttl);
}
function fociz_clear_rate_limit(string $actionKey): void {
require_once __DIR__ . '/cache.php';
$cacheKey = 'rl_' . hash('sha256', $actionKey);
fociz_cache_delete($cacheKey);
}
/**
* Genereert een cryptografisch ondertekende OAuth state parameter waarin de user_id en timestamp veilig zijn opgeslagen.
* Dit voorkomt CSRF en maakt sessieherstel mogelijk bij cross-site OAuth redirects.