Any antibot challenge that does not rely on a third party server?

Hello, is anyone using antibot challenge that does not rely on recaptcha or similar spyware?
I have tried to ask HivePress AI and Lumo, but both gives non working code which does not report error and avoids registration entirely.

Sample **non-**working code:

// 1. Add math challenge to registration form
add_filter(
	'hivepress/v1/forms/user_register',
	function( $form ) {
		// Generate new random numbers each time form renders
		$num1 = rand( 5, 15 );
		$num2 = rand( 5, 15 );
		
		// Store answer in transient with UUID key
		$challenge_id = wp_generate_uuid4();
		set_transient( 'hp_math_answer_' . $challenge_id, $num1 + $num2, HOUR_IN_SECONDS );
		
		$form['fields']['math_challenge_id'] = [
			'type'  => 'hidden',
			'value' => $challenge_id,
		];
		
		$form['fields']['math_challenge'] = [
			'label'       => sprintf( 'What is %d + %d?', $num1, $num2 ),
			'type'        => 'text',
			'required'    => true,
			'_order'      => 100,
		];
		
		return $form;
	},
	1000
);

// 2. Validate answer
add_filter(
	'hivepress/v1/forms/user_register/errors',
	function( $errors, $form ) {
		if ( isset( $_POST['math_challenge'], $_POST['math_challenge_id'] ) ) {
			$challenge_id = sanitize_text_field( $_POST['math_challenge_id'] );
			$user_answer = (int) $_POST['math_challenge'];
			$correct_answer = get_transient( 'hp_math_answer_' . $challenge_id );
			
			if ( false === $correct_answer ) {
				$errors[] = 'Math challenge expired. Please refresh the page.';
			} elseif ( $user_answer !== $correct_answer ) {
				$errors[] = 'Incorrect answer. Please try again.';
			} else {
				// Success - delete transient
				delete_transient( 'hp_math_answer_' . $challenge_id );
			}
		}
		
		return $errors;
	},
	1000,
	2
);

Working code, BUT reliant on a third party service and WP plugin (unwanted in this case) is:

// Add hCaptcha to user register form
add_filter(
	'hivepress/v1/forms/user_register',
	function( $form ) {
		$form['footer'] = '<div id="my-hcaptcha-box">' . do_shortcode('[hcaptcha]') . '</div>' . hivepress()->helper->get_array_value( $form, 'footer' );
		return $form;
	},
	100
);

// Throw error if hCaptcha is missing
add_filter(
	'hivepress/v1/forms/user_register/errors',
	function( $errors, $form ) {
		$result = \HCaptcha\Helpers\API::verify_request();		

		if ( null !== $result ) {
			$errors[] = 'Please solve the hCaptcha.';
		}		
		
		return $errors;
	},
	100,
	2
);

(above hcaptcha code is from this tutorial)

if you do not have working solution and looking for one, are you able to tweak some of these codes to work? Yes, i know this is a weak protection, but i am unable to come up with better as a non-developer. But the idea may be using Javascript in the challenge or some drag/drop action.

Hi @obtrusive170,

I haven’t tested this, but I shared your attempts with another AI who returned this to try instead:

<?php
/**
 * Math CAPTCHA for HivePress registration form.
 *
 * Bugs fixed:
 *  1. Added REQUEST_METHOD guard so a new challenge is only generated on
 *     GET (form render), not on POST (form submit) — preventing transient
 *     orphaning and a mismatched challenge_id on submission.
 *  2. Cast get_transient() result to int before strict comparison, since
 *     transients return strings and (int) !== (string) always fails.
 */

// -------------------------------------------------------------------------
// 1. Add math challenge fields to the registration form (render only).
// -------------------------------------------------------------------------
add_filter(
	'hivepress/v1/forms/user_register',
	function ( $form ) {

		// Only generate a new challenge on GET — not during form submission.
		if ( 'POST' === $_SERVER['REQUEST_METHOD'] ) {
			return $form;
		}

		$num1         = rand( 5, 15 );
		$num2         = rand( 5, 15 );
		$challenge_id = wp_generate_uuid4();

		set_transient( 'hp_math_answer_' . $challenge_id, $num1 + $num2, HOUR_IN_SECONDS );

		// Hidden field — 'hidden' is a native HivePress field type.
		$form['fields']['math_challenge_id'] = [
			'type'  => 'hidden',
			'value' => $challenge_id,
		];

		// Visible question field.
		$form['fields']['math_challenge'] = [
			'label'    => sprintf( 'What is %d + %d?', $num1, $num2 ),
			'type'     => 'text',
			'required' => true,
			'_order'   => 100,
		];

		return $form;
	},
	1000
);

// -------------------------------------------------------------------------
// 2. Validate the math answer via the HivePress form errors filter.
//    hivepress/v1/forms/{form_name}/errors is the correct hook pattern.
// -------------------------------------------------------------------------
add_filter(
	'hivepress/v1/forms/user_register/errors',
	function ( $errors, $form ) {

		if ( ! isset( $_POST['math_challenge'], $_POST['math_challenge_id'] ) ) {
			return $errors;
		}

		$challenge_id   = sanitize_text_field( wp_unslash( $_POST['math_challenge_id'] ) );
		$user_answer    = (int) sanitize_text_field( wp_unslash( $_POST['math_challenge'] ) );
		$stored         = get_transient( 'hp_math_answer_' . $challenge_id );

		if ( false === $stored ) {
			$errors[] = 'Math challenge expired. Please refresh the page and try again.';
		} elseif ( $user_answer !== (int) $stored ) {
			// Bug fix: cast $stored to int — transients return strings,
			// so strict !== against (int) $user_answer would always fail.
			$errors[] = 'Incorrect answer. Please try again.';
		} else {
			// Correct — consume the transient to prevent replay.
			delete_transient( 'hp_math_answer_' . $challenge_id );
		}

		return $errors;
	},
	1000,
	2
);

I’m personally looking into using Cloudflare Turnstile, but I’m still working on connecting it to HivePress’s forms.

I hope this helps!

Let us know how you get on :slightly_smiling_face:

Cheers,
Chris :victory_hand:

2 Likes

Thanks for sharing the solution.

We plan to add hCaptcha support in future updates – it seems to guarantee user privacy, but if a self-hosted challenge is required, then a fully custom implementation is needed for sure. The simplest but not fully effective solution may be adding a “honeypot” checkbox to the registration form via the hivepress/v1/forms/user_register hook.

1 Like

Thank you for a good news that more private captcha (hcaptcha) is planned and @ChrisB PHP snippet worked (one needs to remove 1st line of it) to add working math challenge to a registration form. Hive AI have been able to modify it to work also optionally on a reviews form. You had to use some clever prompt or right AI model, I am surprised it works after many failed attempts of mine.

Hi @obtrusive170,

Yes, plugins like Code Snippets automatically add the <?php part, so you don’t need to include the first line of the snippet I shared above.

I’m not sure if you seen my other topic, but in case you’re interested, I’ve managed to come up with a working Cloudflare Turnstile bridge for HivePress.

“Cloudflare Turnstile is a free, privacy-first CAPTCHA alternative that verifies human users without forcing them to solve puzzles like selecting traffic lights or typing blurry text. It uses invisible, background JavaScript challenges—like proof-of-work tests and browser API probing—to analyze client behavior and distinguish real users from automated bots.”

You can also read more about Cloudflare Turnstile here.

I hope this helps!

Cheers,
Chris :victory_hand:

2 Likes