Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CF-Turnstile support #4683

Open
wants to merge 9 commits into
base: feature
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 19 additions & 1 deletion admin/modules/config/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -999,7 +999,9 @@
$mybb->input['upsetting']['recaptchapublickey'],
$mybb->input['upsetting']['recaptchascore'],
$mybb->input['upsetting']['hcaptchaprivatekey'],
$mybb->input['upsetting']['hcaptchapublickey']
$mybb->input['upsetting']['hcaptchapublickey'],
$mybb->input['upsetting']['cfturnstileprivatekey'],
$mybb->input['upsetting']['cfturnstilepublickey']
))
{
$captchaimage = $mybb->input['upsetting']['captchaimage'];
Expand All @@ -1008,6 +1010,8 @@
$recaptchascore = $mybb->input['upsetting']['recaptchascore'];
$hcaptchaprivatekey = $mybb->input['upsetting']['hcaptchaprivatekey'];
$hcaptchapublickey = $mybb->input['upsetting']['hcaptchapublickey'];
$cfturnstileprivatekey = $mybb->input['upsetting']['cfturnstileprivatekey'];
$cfturnstilepublickey = $mybb->input['upsetting']['cfturnstilepublickey'];

if(in_array($captchaimage, array(captcha::NOCAPTCHA_RECAPTCHA, captcha::RECAPTCHA_INVISIBLE)) && (!$recaptchaprivatekey || !$recaptchapublickey))
{
Expand All @@ -1021,6 +1025,10 @@
{
$set_captcha_image = true;
}
else if($captchaimage == captcha::CFTURNSTILE && (!$cfturnstileprivatekey || !$cfturnstilepublickey))
{
$set_captcha_image = true;
}
}

//Checking settings for reCAPTCHA or hCaptcha and public/private key not set?
Expand All @@ -1030,6 +1038,8 @@
$recaptchascore = $mybb->settings['recaptchascore'];
$hcaptchaprivatekey = $mybb->settings['hcaptchaprivatekey'];
$hcaptchapublickey = $mybb->settings['hcaptchapublickey'];
$cfturnstileprivatekey = $mybb->settings['cfturnstileprivatekey'];
$cfturnstilepublickey = $mybb->settings['cfturnstilepublickey'];

if(in_array($captchaimage, array(captcha::NOCAPTCHA_RECAPTCHA, captcha::RECAPTCHA_INVISIBLE)) && (!$recaptchaprivatekey || !$recaptchapublickey))
{
Expand All @@ -1043,6 +1053,10 @@
{
$set_captcha_image = true;
}
else if($captchaimage == captcha::CFTURNSTILE && ( !$cfturnstileprivatekey || !$cfturnstilepublickey))
{
$set_captcha_image = true;
}
if($set_captcha_image){
$mybb->input['upsetting']['captchaimage'] = captcha::DEFAULT_CAPTCHA;
$lang->success_settings_updated .= $lang->success_settings_updated_captchaimage;
Expand Down Expand Up @@ -2001,6 +2015,10 @@ function print_setting_peekers()
'new Peeker($("#setting_captchaimage"), $("#row_setting_hcaptchaprivatekey, #row_setting_hcaptchaprivatekey"), /(6|7)/, false)',
'new Peeker($("#setting_captchaimage"), $("#row_setting_hcaptchatheme"), 6, false)',
'new Peeker($("#setting_captchaimage"), $("#row_setting_hcaptchasize"), 6, false)',
'new Peeker($("#setting_captchaimage"), $("#row_setting_cfturnstilepublickey, #row_setting_cfturnstileprivatekey"), /(8|9)/, false)',
'new Peeker($("#setting_captchaimage"), $("#row_setting_cfturnstileprivatekey, #row_setting_cfturnstileprivatekey"), /(8|9)/, false)',
'new Peeker($("#setting_captchaimage"), $("#row_setting_cfturnstiletheme"), 9, false)',
'new Peeker($("#setting_captchaimage"), $("#row_setting_cfturnstilesize"), 9, false)',
'new Peeker($(".setting_contact"), $("#row_setting_contact_guests, #row_setting_contact_badwords, #row_setting_contact_maxsubjectlength, #row_setting_contact_minmessagelength, #row_setting_contact_maxmessagelength"), 1, true)',
'new Peeker($(".setting_enablepruning"), $("#row_setting_enableprunebyposts, #row_setting_pruneunactived, #row_setting_prunethreads"), 1, true)',
'new Peeker($(".setting_enableprunebyposts"), $("#row_setting_prunepostcount, #row_setting_dayspruneregistered, #row_setting_prunepostcountall"), 1, true)',
Expand Down
2 changes: 1 addition & 1 deletion contact.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
define("IN_MYBB", 1);
define('THIS_SCRIPT', 'contact.php');

$templatelist = "contact,post_captcha,post_captcha_recaptcha_invisible,post_captcha_nocaptcha,post_captcha_hcaptcha_invisible,post_captcha_hcaptcha";
$templatelist = "contact,post_captcha,post_captcha_recaptcha_invisible,post_captcha_nocaptcha,post_captcha_cfturnstile,post_captcha_hcaptcha_invisible,post_captcha_hcaptcha";

require_once "./global.php";
require_once MYBB_ROOT.'inc/class_captcha.php';
Expand Down
61 changes: 61 additions & 0 deletions inc/class_captcha.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class captcha
* 6 = hCaptcha
* 7 = hCaptcha invisible
* 8 = reCAPTCHA v3
* 9 = CF Turnstile
*
* @var int
*/
Expand All @@ -60,6 +61,7 @@ class captcha
const HCAPTCHA = 6;
const HCAPTCHA_INVISIBLE = 7;
const RECAPTCHA_V3 = 8;
const CFTURNSTILE = 9;

/**
* The template to display the CAPTCHA in
Expand Down Expand Up @@ -139,6 +141,10 @@ function __construct($build = false, $template = "")
{
$this->captcha_template .= "_recaptcha_invisible";
}
elseif($this->type == captcha::CFTURNSTILE)
{
$this->captcha_template .= "_cfturnstile";
}
}

// Work on which CAPTCHA we've got installed
Expand All @@ -164,6 +170,17 @@ function __construct($build = false, $template = "")
$this->build_hcaptcha();
}
}
elseif($this->type == captcha::CFTURNSTILE && $mybb->settings['cfturnstilepublickey'] && $mybb->settings['cfturnstileprivatekey'])
{
// JS and backend server validation
$this->server = "//challenges.cloudflare.com/turnstile/v0/api.js";
$this->verify_server = "https://challenges.cloudflare.com/turnstile/v0/siteverify";

if($build == true)
{
$this->build_cfturnstile();
}
}
elseif($this->type == captcha::DEFAULT_CAPTCHA)
{
if(!function_exists("imagecreatefrompng"))
Expand Down Expand Up @@ -227,6 +244,19 @@ function build_hcaptcha()
eval("\$this->html = \"".$templates->get($this->captcha_template, 1, 0)."\";");
}

function build_cfturnstile()
{
global $lang, $mybb, $templates, $theme;

// This will build a hCaptcha
$server = $this->server;
$public_key = $mybb->settings['cfturnstilepublickey'];
$captcha_theme = $mybb->settings['cfturnstiletheme'];
$captcha_size = $mybb->settings['cfturnstilesize'];

eval("\$this->html = \"".$templates->get($this->captcha_template, 1, 0)."\";");
}

/**
* @return string
*/
Expand Down Expand Up @@ -390,6 +420,37 @@ function validate_captcha()
}
}
}
elseif($this->type === self::CFTURNSTILE)
{
$response = $mybb->get_input('cf-turnstile-response');
if(!$response || strlen($response) == 0)
{
$this->set_error($lang->invalid_cfturnstile);
}
else
{
// Contact CF-Turnstile and see if our CF-Turnstile request was successful
$response = fetch_remote_file($this->verify_server, array(
'secret' => $mybb->settings['cfturnstileprivatekey'],
'remoteip' => $session->ipaddress,
'response' => $response
));

if($response == false)
{
$this->set_error($lang->invalid_cfturnstile_transmit);
}
else
{
$answer = json_decode($response, true);
if($answer['success'] != 'true')
{
// We got it wrong! Oh no...
$this->set_error($lang->invalid_cfturnstile);
}
}
}
}
$plugins->run_hooks('captcha_validate_end', $this);

if(count($this->errors) > 0)
Expand Down
3 changes: 3 additions & 0 deletions inc/languages/english/global.lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -448,15 +448,18 @@

$l['invalid_post_code'] = "Authorization code mismatch. Are you accessing this function correctly? Please go back and try again.";
$l['invalid_nocaptcha'] = "Please solve the reCAPTCHA to verify that you're not a robot.";
$l['invalid_cfturnstile'] = "Please solve the CF-Turnstile captcha to verify that you're not a robot.";
$l['invalid_hcaptcha'] = "Please solve the hCaptcha to verify that you're not a robot.";
$l['invalid_captcha_verify'] = "The image verification code that you entered was incorrect. Please enter the code exactly how it appears in the image.";
$l['image_verification'] = "Image Verification";
$l['human_verification'] = "Human Verification";
$l['verification_note'] = "Please enter the text contained within the image into the text box below it. This process is used to prevent automated spam bots.";
$l['verification_note_nocaptcha'] = "Please tick the checkbox that you see below. This process is used to prevent automated spam bots.";
$l['verification_note_cfturnstile'] = "Please tick the checkbox that you see below. This process is used to prevent automated spam bots.";
$l['verification_note_hcaptcha'] = "Please tick the checkbox that you see below. This process is used to prevent automated spam bots.";
$l['verification_subnote'] = "(case insensitive)";
$l['invalid_nocaptcha_transmit'] = "An error occurred with the human verification by reCAPTCHA. Please try again.";
$l['invalid_cfturnstile_transmit'] = "An error occurred with the human verification by CF-Turnstile captcha. Please try again.";
$l['invalid_hcaptcha_transmit'] = "An error occurred with the human verification by hCaptcha. Please try again.";
$l['captcha_fetch_failure'] = 'There was an error fetching the new captcha.';
$l['question_fetch_failure'] = 'There was an error fetching the new question.';
Expand Down
27 changes: 26 additions & 1 deletion install/resources/mybb_theme.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5593,6 +5593,18 @@ if(use_xmlhttprequest == "1")
<td><script type="text/javascript" src="{$server}"></script><div class="h-captcha" data-sitekey="{$public_key}" data-theme="{$captcha_theme}" data-size="{$captcha_size}"></div></td>
</tr>
</table>
</fieldset>]]></template>
<template name="member_register_regimage_cfturnstile" version="1823"><![CDATA[<br />
<fieldset class="trow2">
<legend><strong>{$lang->human_verification}</strong></legend>
<table cellspacing="0" cellpadding="{$theme['tablespace']}">
<tr>
<td><span class="smalltext">{$lang->verification_note_cfturnstile}</span></td>
</tr>
<tr>
<td><script type="text/javascript" src="{$server}"></script><div class="h-captcha" data-sitekey="{$public_key}" data-theme="{$captcha_theme}" data-size="{$captcha_size}"></div></td>
</tr>
</table>
</fieldset>]]></template>
<template name="member_register_requiredfields" version="1800"><![CDATA[<br />
<fieldset class="trow2">
Expand Down Expand Up @@ -9601,7 +9613,20 @@ if(use_xmlhttprequest == "1")
<td><span class="smalltext">{$lang->verification_note_hcaptcha}</span></td>
</tr>
<tr>
<td><script type="text/javascript" src="{$server}"></script><div class="h-captcha" data-sitekey="{$public_key}" data-theme="{$captcha_theme}" data-size="{$captcha_size}"></div></td>
<td><script type="text/javascript" src="{$server}"></script><div class="cf-turnstile" data-sitekey="{$public_key}" data-theme="{$captcha_theme}" data-size="{$captcha_size}"></div></td>
</tr>
</table>
</td>
</tr>]]></template>
<template name="post_captcha_cfturnstile" version="1823"><![CDATA[<tr id="captcha_trow">
<td class="trow1" valign="top"><strong>{$lang->human_verification}</strong></td>
<td class="trow1">
<table style="width: 300px; padding: 4px;">
<tr>
<td><span class="smalltext">{$lang->verification_note_cfturnstile}</span></td>
</tr>
<tr>
<td><script type="text/javascript" src="{$server}"></script><div class="cf-turnstile" data-sitekey="{$public_key}" data-theme="{$captcha_theme}" data-size="{$captcha_size}"></div></td>
</tr>
</table>
</td>
Expand Down