How to verify cloudflare turnstile response on WordPress

Hi, is there a way to verify $_POST[‘cf-turnstile-response’] is a valid response or not like is_valid_captcha_response that I use for reCaptcha.?

here is my code

function verify_cf_turnstile() { 
    $recaptcha = $_POST['cf-turnstile-response']; 
    if(empty($recaptcha)){ 
        wp_die(__("<b>ERROR: </b><b>Please click the captcha checkbox.</b><p><a href='javascript:history.back()'>« Back</a></p>")); 
    }elseif(!is_valid_captcha_response($recaptcha)){ 
        wp_die(__("<b>Sorry, spam detected!</b>")); 
    } 
} 

The $_POST[‘cf-turnstile-response’] is not empty, I get a long string if var_dump it.

It allows me to proceed if the turnstile is a success, but, if I am using the always block site key to get a failure, I am getting click the checkbox response.

And if I am using the force a challenge and click on the checkbox, then I am getting the spam detected response.

How to fix that? iam still a beginner in PHP and coding btw.

Hi! Have you seen this discussion:

Yes, i saw it. and at the end of discussion, he still can’t verify his $_POST token right? same as me here.

so with this one, i must have a $results[‘success’] result,

$response = json_decode($verify);

    if($response->success) {
        $results['success'] = $response->success;
    } else {
        $results['success'] = false;
    }

if(empty($postdata)){ 
        wp_die(__("<b>ERROR: </b><b>Please click the captcha checkbox.</b><p><a href='javascript:history.back()'>« Back</a></p>")); 
    } elseif(!$results['success']){ 
        wp_die(__("<b>Sorry, spam detected!</b>")); 
    } else {
        return true;
    }

But is the test key for force challenge cant be a success? it’s detected as spam because it’s not a success.

and why the failure test key is not giving the $_POST[‘cf-turnstile-response’] , icant mark it as spam then.

the key are from the Cloudflare dummy key

No, at the end of the PHP $_POST discussion, he WAS able to verify the token after adding an attribute, I believe. Once he did that, the response token appeared where he expected it.

So, if you’re using the test keys, I imagine you wouldn’t get a “success” response of any kind since the keys for “unsuccessful” responses (to simulate a failed browser challenge or whatever). I don’t know what keys the original poster used in the other PHP thread. Maybe you could post your question in that thread, if it’s not closed.

Also, do you need to “roll your own” solution here or can you use an existing Wordpress plugin?

That was his reply.

Thank you for your reply.

Yes, I am refrain using plugins at this time for some reasons.

Yes, he’s talking about his logic to control how the widget works on his page. He’s now getting the response in $_POST, where he expected. If you look through all of the discussion, you’ll find the solution that worked (i.e. caused the response token to appear in $_POST).

Given security issues related to Wordpress and plugins, I can understand your hesitancy in using one. :slight_smile:

Maybe if you posted the HTML snipet of your form so we can see how you have the Turnstile div defined, etc.

Yes, I am sorry if I have written the wrong impression about my problem. I did get the response in $_POST also, however, similar to his reply, I want to make sure the data is sent IF the CF server-verify comes back with OK or success for interactive challenge case.

Gotcha. So, the response token you’re getting via $_POST is what you need to send to the siteverify endpoint on the back-end. The fact you have a response in $_POST means the browser-side challenge worked. So, I think you’re flow would be:

  1. Load the page such that Turnstile runs the browser challenges
  2. When the user clicks “submit”, the form data is in $_POST, along with the response from the browser challenges
  3. Get the response token in $_POST and send it to the siteverify endpoint for verification
  4. If the call to siteverify works, meaning siteverify verifies the response token you sent, it’s ok to process your form data

If the call to siteverify fails, you can return to the browser the completed form with some kind of error message instructing the visitor to submit the form again or something. The Turnstile widget, itself, won’t prevent the submission of the form.

1 Like