Fix captcha

This commit is contained in:
Esteban
2026-06-29 16:34:35 +02:00
parent 4bab6548f7
commit ac292fbcc4
+32 -27
View File
@@ -1,17 +1,21 @@
<?php <?php
// Démarrage de la session
session_start(); session_start();
// Recharger une nouvelle série si demandé
if (isset($_GET['reload']) && $_GET['reload'] === '1') {
unset($_SESSION['captcha_round']);
header('Location: ./captcha.php');
exit;
}
// Si le captcha est déjà validé, rediriger vers l'accueil // Si le captcha est déjà validé, rediriger vers l'accueil
if (isset($_SESSION['captcha_valid']) && $_SESSION['captcha_valid'] === true) { if (isset($_SESSION['captcha_valid']) && $_SESSION['captcha_valid'] === true) {
header('Location: ./index.php'); header('Location: ./index.php');
exit; exit;
} }
// Nombre maximum de tentatives
$maxAttempts = 3; $maxAttempts = 3;
// Tableau de sujets normaux
$normalSubjects = [ $normalSubjects = [
'Votre rendez-vous est confirmé', 'Votre rendez-vous est confirmé',
'Photo de famille', 'Photo de famille',
@@ -117,7 +121,6 @@ $normalSubjects = [
'Dernières informations' 'Dernières informations'
]; ];
// Tableau de expéditeurs normaux
$normalSenders = [ $normalSenders = [
'Docteur Martin', 'Docteur Martin',
'Julie', 'Julie',
@@ -141,7 +144,6 @@ $normalSenders = [
'Service facturation' 'Service facturation'
]; ];
// Tableau de sujets spam
$spamSubjects = [ $spamSubjects = [
'URGENT !!! VOTRE COMPTE SERA SUPPRIMÉ AUJOURDHUI', 'URGENT !!! VOTRE COMPTE SERA SUPPRIMÉ AUJOURDHUI',
'FÉLICITATIONS !!! VOUS AVEZ GAGNÉ 5000 € MAINTENANT', 'FÉLICITATIONS !!! VOUS AVEZ GAGNÉ 5000 € MAINTENANT',
@@ -165,7 +167,6 @@ $spamSubjects = [
'CONFIRMEZ VOTRE IDENTITÉ POUR RECEVOIR VOTRE ARGENT' 'CONFIRMEZ VOTRE IDENTITÉ POUR RECEVOIR VOTRE ARGENT'
]; ];
// Tableau de expéditeurs spam
$spamSenders = [ $spamSenders = [
'service-urgent@compte-bloque-now.biz', 'service-urgent@compte-bloque-now.biz',
'cadeau-gratuit@super-offre-win.click', 'cadeau-gratuit@super-offre-win.click',
@@ -177,7 +178,6 @@ $spamSenders = [
'alerte@compte-fermeture.click' 'alerte@compte-fermeture.click'
]; ];
// Tableau de previews normaux
$normalPreviews = [ $normalPreviews = [
'Bonjour, nous vous confirmons votre rendez-vous prévu cette semaine.', 'Bonjour, nous vous confirmons votre rendez-vous prévu cette semaine.',
'Je vous envoie les informations demandées, bonne journée.', 'Je vous envoie les informations demandées, bonne journée.',
@@ -191,7 +191,6 @@ $normalPreviews = [
'Vous trouverez ci-joint les éléments utiles.' 'Vous trouverez ci-joint les éléments utiles.'
]; ];
// Tableau de previews spam
$spamPreviews = [ $spamPreviews = [
'Cliquez tout de suite sinon votre compte sera fermé dans quelques minutes.', 'Cliquez tout de suite sinon votre compte sera fermé dans quelques minutes.',
'Paiement obligatoire immédiat pour débloquer la situation.', 'Paiement obligatoire immédiat pour débloquer la situation.',
@@ -201,7 +200,15 @@ $spamPreviews = [
'Dernier avertissement officiel avant blocage définitif.' 'Dernier avertissement officiel avant blocage définitif.'
]; ];
// Fonction pour construire un round de boîte de réception function firstLetterSafe(string $text): string
{
if (function_exists('mb_substr') && function_exists('mb_strtoupper')) {
return mb_strtoupper(mb_substr($text, 0, 1, 'UTF-8'), 'UTF-8');
}
return strtoupper(substr($text, 0, 1));
}
function buildInboxRound( function buildInboxRound(
array $normalSubjects, array $normalSubjects,
array $normalSenders, array $normalSenders,
@@ -211,7 +218,6 @@ function buildInboxRound(
array $spamPreviews, array $spamPreviews,
int $maxAttempts int $maxAttempts
): array { ): array {
$normalPool = []; $normalPool = [];
foreach ($normalSubjects as $index => $subject) { foreach ($normalSubjects as $index => $subject) {
$normalPool[] = [ $normalPool[] = [
@@ -236,16 +242,13 @@ function buildInboxRound(
]; ];
} }
// Mélanger les tableaux
shuffle($normalPool); shuffle($normalPool);
shuffle($spamPool); shuffle($spamPool);
// Sélectionner 9 emails normaux et 1 spam
$selected = array_slice($normalPool, 0, 9); $selected = array_slice($normalPool, 0, 9);
$selected[] = $spamPool[0]; $selected[] = $spamPool[0];
shuffle($selected); shuffle($selected);
// Retourner le round
return [ return [
'token' => bin2hex(random_bytes(16)), 'token' => bin2hex(random_bytes(16)),
'correct_id' => $spamPool[0]['id'], 'correct_id' => $spamPool[0]['id'],
@@ -266,47 +269,51 @@ if (!isset($_SESSION['captcha_round']) || !is_array($_SESSION['captcha_round']))
); );
} }
// Récupérer le round actuel
$round = $_SESSION['captcha_round']; $round = $_SESSION['captcha_round'];
$error = ''; $error = '';
$success = false; $success = false;
$locked = false; $locked = false;
if (!isset($round['emails']) || !is_array($round['emails'])) {
$_SESSION['captcha_round'] = buildInboxRound(
$normalSubjects,
$normalSenders,
$normalPreviews,
$spamSubjects,
$spamSenders,
$spamPreviews,
$maxAttempts
);
$round = $_SESSION['captcha_round'];
}
// Si formulaire soumis via POST
if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$postedToken = $_POST['captcha_token'] ?? ''; $postedToken = $_POST['captcha_token'] ?? '';
$selectedMail = $_POST['selected_mail'] ?? ''; $selectedMail = $_POST['selected_mail'] ?? '';
// Si token invalide
if (!hash_equals($round['token'], $postedToken)) { if (!hash_equals($round['token'], $postedToken)) {
$error = 'Session invalide, recharge la page.'; $error = 'Session invalide, recharge la page.';
// Si plus d'essais
} elseif (($round['attempts_left'] ?? 0) <= 0) { } elseif (($round['attempts_left'] ?? 0) <= 0) {
$locked = true; $locked = true;
$error = 'Tu nas plus dessais. Recharge une nouvelle série.'; $error = 'Tu nas plus dessais. Recharge une nouvelle série.';
// Si mail incorrect
} elseif ($selectedMail !== $round['correct_id']) { } elseif ($selectedMail !== $round['correct_id']) {
$_SESSION['captcha_round']['attempts_left']--; $_SESSION['captcha_round']['attempts_left']--;
$round = $_SESSION['captcha_round']; $round = $_SESSION['captcha_round'];
// Si plus d'essais après décrémentation
if (($round['attempts_left'] ?? 0) <= 0) { if (($round['attempts_left'] ?? 0) <= 0) {
$locked = true; $locked = true;
$error = 'Perdu. Tu nas plus dessais. Recharge une nouvelle série.'; $error = 'Perdu. Tu nas plus dessais. Recharge une nouvelle série.';
// Sinon, message d'erreur
} else { } else {
$error = 'Ce nest pas le bon mail. Regarde mieux le message le plus agressif ou trop urgent.'; $error = 'Ce nest pas le bon mail. Regarde mieux le message le plus agressif ou trop urgent.';
} }
// Si mail correct
} else { } else {
$_SESSION['captcha_valid'] = true; $_SESSION['captcha_valid'] = true;
unset($_SESSION['captcha_round']); unset($_SESSION['captcha_round']);
$success = true; $success = true;
} }
} }
// Récupérer le nombre d'essais restants
$attemptsLeft = $round['attempts_left'] ?? 0;
// Afficher le captcha $attemptsLeft = $round['attempts_left'] ?? 0;
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="fr"> <html lang="fr">
@@ -388,7 +395,7 @@ $attemptsLeft = $round['attempts_left'] ?? 0;
> >
<span class="mail-row"> <span class="mail-row">
<span class="mail-avatar"> <span class="mail-avatar">
<?php echo htmlspecialchars(mb_strtoupper(mb_substr($mail['sender'], 0, 1, 'UTF-8'), 'UTF-8'), ENT_QUOTES, 'UTF-8'); ?> <?php echo htmlspecialchars(firstLetterSafe($mail['sender']), ENT_QUOTES, 'UTF-8'); ?>
</span> </span>
<span class="mail-sender"> <span class="mail-sender">
@@ -437,5 +444,3 @@ $attemptsLeft = $round['attempts_left'] ?? 0;
</main> </main>
</body> </body>
</html> </html>