| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- <?php
- require_once "../env.inc.php";
- require_once "../conf.inc.php";
- require_once DIR_PHP_LAYOUTS . "header.php";
- secureSession::start();
- require_once "../access.inc.php";
- require_once DIR_PHP_LAYOUTS . "cms.session.php";
- // Validation CSRF pour les formulaires POST (sauf exceptions)
- if ($_SERVER['REQUEST_METHOD'] === 'POST' && core::ifPost("from")) {
- $from = core::getPost("from");
- // ========================================
- // PROTECTION LOGIN : Rate Limiting + Honeypot
- // ========================================
- $loginActions = ['login', 'authenticator'];
- if (in_array($from, $loginActions)) {
- $email = core::getPost('email') ?? '';
- // 1. Vérification du honeypot (anti-bot)
- if (!loginSecurity::checkHoneypot('website')) {
- error_log("[SECURITY] Bot detected via honeypot | IP: " . loginSecurity::getClientIP());
- http_response_code(403);
- header('Content-Type: application/json');
- echo json_encode(['error' => 'Requête invalide', 'blocked' => true]);
- exit();
- }
- // 2. Vérification du rate limiting
- $blockStatus = loginSecurity::checkBlocked($email);
- if ($blockStatus['blocked']) {
- error_log("[SECURITY] Blocked login attempt | IP: " . loginSecurity::getClientIP() . " | Email: $email");
- http_response_code(429); // Too Many Requests
- header('Content-Type: application/json');
- echo json_encode([
- 'success' => false,
- 'blocked' => true,
- 'remaining_time' => $blockStatus['remaining_time'],
- 'message' => $blockStatus['message']
- ]);
- exit();
- }
- // 3. Appliquer le throttling (délai progressif)
- loginSecurity::applyThrottle($email);
- }
- // Liste des actions nécessitant une protection CSRF (avec consommation du token)
- $csrfProtectedActions = [
- 'login',
- 'user-edit',
- 'user-password',
- 'parametres-clients',
- 'evenement-fiche',
- 'lottery-fiche',
- 'alertes-emails',
- 'parametres-teams-edit',
- 'rh-import',
- 'restore'
- ];
- // Actions qui valident le token SANS le consommer (pour les pré-vérifications AJAX)
- $csrfCheckOnlyActions = [
- 'authenticator' // Vérification Google Auth avant login - ne consomme pas le token
- ];
- // Si l'action nécessite une protection CSRF
- if (in_array($from, $csrfProtectedActions)) {
- $isValid = false;
- // Tentative validation via header (AJAX)
- if (!empty($_SERVER['HTTP_X_CSRF_TOKEN'])) {
- $isValid = csrf::validateHeader('cms-ajax', 'X-CSRF-Token');
- if (!$isValid) {
- $isValid = csrf::validateHeader('login-ajax', 'X-CSRF-Token');
- }
- }
- // Tentative validation via POST (formulaire) - consomme le token
- if (!$isValid && isset($_POST['csrf_token'])) {
- $isValid = csrf::validatePost('login-form', 'csrf_token', 3600, true);
- }
- // Si le token est invalide
- if (!$isValid) {
- error_log("CSRF validation failed for action: $from from IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
- if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
- http_response_code(403);
- header('Content-Type: application/json');
- echo json_encode([
- 'success' => false,
- 'error' => 'csrf_failed',
- 'message' => 'Token de sécurité invalide ou expiré. Veuillez recharger la page.'
- ]);
- exit();
- } else {
- alert::recError("Erreur de sécurité. Veuillez réessayer.");
- header('Location: ' . ($_SERVER['HTTP_REFERER'] ?? '/'));
- exit();
- }
- }
- }
- // Si l'action est une pré-vérification (valide sans consommer)
- if (in_array($from, $csrfCheckOnlyActions)) {
- $isValid = false;
- // Validation via POST sans consommer le token
- if (isset($_POST['csrf_token'])) {
- $isValid = csrf::validatePost('login-form', 'csrf_token', 3600, false); // false = ne pas consommer
- }
- if (!$isValid) {
- error_log("CSRF check failed for action: $from from IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
- http_response_code(403);
- header('Content-Type: application/json');
- echo json_encode(['error' => 'Token invalide']);
- exit();
- }
- }
- }
- if (debug::isFile("submit") and (core::ifPost() or core::ifFiles())) {
- core::ifPost() ? debug::logSession(core::getPost()) : NULL;
- core::ifFiles() ? debug::logSession(core::getFiles()) : NULL;
- }
- get::submit();
|