Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 51 additions & 5 deletions application/libraries/FusionCaptcha.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ public function generate_challenge(): array
$ip = $this->get_user_ip();
$data = $this->read_ip_data($ip);

// Challenges are bound to the user-agent hash when bind_ua is enabled.
// If a different browser behind the same IP asks for a challenge, do not
// reuse the previous browser's challenge because redemption would fail
// with ua_mismatch.
if ($this->settings['bind_ua']) {
$currentUa = $this->user_agent_hash();
if (($data['ua'] ?? '') !== $currentUa) {
$data['ua'] = $currentUa;
$data['challenge'] = null;
}
}

// Rate limit check (stored inside the same IP file)
if (!$this->rate_limit_in_data($data, 'challenge', $this->settings['max_challenges_per_minute'])) {
return ['success' => false, 'error' => 'rate_limited'];
Expand Down Expand Up @@ -305,8 +317,7 @@ public function garbage_collect(): void
return;
}

$prefix = 'captcha/captcha_'; // prefix used in cache_save
$files = glob('writable/cache/data/' . $prefix . '*');
$files = glob($this->cache_path() . '/captcha_*.cache');

if (!is_array($files)) {
return;
Expand Down Expand Up @@ -375,7 +386,7 @@ protected function get_user_ip(): string
return $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
}

protected function cache_save(string $key, $value, int $ttl): void
protected function cache_path(): string
{
$cachePath = WRITEPATH . 'cache/data/captcha';
if (!is_dir($cachePath)) {
Expand All @@ -384,12 +395,47 @@ protected function cache_save(string $key, $value, int $ttl): void
}
@chmod($cachePath, 0775);

$this->CI->cache->save('captcha/captcha_' . $key, $value, $ttl);
return $cachePath;
}

protected function cache_file(string $key): string
{
$safeKey = preg_replace('/[^A-Za-z0-9_\-]/', '_', $key);
return $this->cache_path() . '/captcha_' . $safeKey . '.cache';
}

protected function cache_save(string $key, $value, int $ttl): void
{
// FusionCaptcha must keep challenge/token state even when FusionCMS'
// global data cache is disabled.
$payload = [
'expiration' => time() + $ttl,
'content' => $value,
];

$file = $this->cache_file($key);
@file_put_contents($file, json_encode($payload), LOCK_EX);
@chmod($file, 0640);
}

protected function cache_get(string $key)
{
return $this->CI->cache->get('captcha/captcha_' . $key);
$file = $this->cache_file($key);
if (!is_file($file)) {
return false;
}

$payload = json_decode((string) @file_get_contents($file), true);
if (!is_array($payload) || !array_key_exists('expiration', $payload)) {
return false;
}

if ((int) $payload['expiration'] <= time()) {
@unlink($file);
return false;
}

return $payload['content'] ?? false;
}

protected function base64url_encode(string $data): string
Expand Down
1 change: 1 addition & 0 deletions application/modules/admin/language/english/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@
'dark' => 'Dark',
'light' => 'Light',
'image_captcha' => 'Image captcha',
'fusion_captcha' => 'Fusion captcha',
'google_recaptcha_v2' => 'Google reCAPTCHA v2',
'google_recaptcha_v3' => 'Google reCAPTCHA v3',
'total_players_online' => 'Total players online',
Expand Down
1 change: 1 addition & 0 deletions application/modules/admin/language/france/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@
'dark' => 'Sombre',
'light' => 'Clair',
'image_captcha' => 'Captcha d\'image',
'fusion_captcha' => 'Captcha Fusion',
'google_recaptcha_v2' => 'Google reCAPTCHA v2',
'google_recaptcha_v3' => 'Google reCAPTCHA v3',
'total_players_online' => 'Total des joueurs en ligne',
Expand Down
1 change: 1 addition & 0 deletions application/modules/admin/language/persian/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@
'dark' => 'تیره',
'light' => 'روشن',
'image_captcha' => 'کپچای تصویری',
'fusion_captcha' => 'کپچای Fusion',
'google_recaptcha_v2' => 'گوگل ریکپچا v2',
'google_recaptcha_v3' => 'گوگل ریکپچا v3',
'total_players_online' => 'مجموع بازیکنان آنلاین',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@
'dark' => 'Escuro',
'light' => 'Claro',
'image_captcha' => 'Captcha de imagem',
'fusion_captcha' => 'Captcha Fusion',
'google_recaptcha_v2' => 'Google reCAPTCHA v2',
'google_recaptcha_v3' => 'Google reCAPTCHA v3',
'total_players_online' => 'Total de jogadores online',
Expand Down
1 change: 1 addition & 0 deletions application/modules/admin/language/spanish/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@
'dark' => 'Oscuro',
'light' => 'Claro',
'image_captcha' => 'Captcha de imagen',
'fusion_captcha' => 'Captcha Fusion',
'google_recaptcha_v2' => 'Google reCAPTCHA v2',
'google_recaptcha_v3' => 'Google reCAPTCHA v3',
'total_players_online' => 'Total de jugadores en línea',
Expand Down
Loading