Skip to content

Instantly share code, notes, and snippets.

@opentechnologist
Created February 4, 2026 07:13
Show Gist options
  • Select an option

  • Save opentechnologist/42d5a8ae9a71196c2384082e53fd246b to your computer and use it in GitHub Desktop.

Select an option

Save opentechnologist/42d5a8ae9a71196c2384082e53fd246b to your computer and use it in GitHub Desktop.
a simple php script to determine if turnstile setup is working properly.
<?php
/**
* Simple Turnstile Setup Testing
* Author: Mario Flores Rey II <mr3y2@yahoo.com>
*
* Minimal, pure-PHP script for testing a Cloudflare Turnstile setup.
* Compatible with PHP 5.6.40+. Remembers verification for N minutes.
*
* Not for production use.
*/
define('SITE_TEST_KEY_ALWAYS_PASS_VISIBLE', '1x00000000000000000000AA');
define('SITE_TEST_KEY_ALWAYS_FAIL_VISIBLE', '2x00000000000000000000AB');
define('SITE_TEST_KEY_ALWAYS_PASS_INVISIBLE', '1x00000000000000000000BB');
define('SITE_TEST_KEY_ALWAYS_FAIL_INVISIBLE', '2x00000000000000000000BB');
define('SITE_TEST_KEY_ALWAYS_CHALLENGE', '3x00000000000000000000FF');
define('SECRET_TEST_KEY_ALWAYS_PASS', '1x0000000000000000000000000000000AA');
define('SECRET_TEST_KEY_ALWAYS_FAIL', '2x0000000000000000000000000000000AA');
define('SECRET_TEST_KEY_ALWAYS_FAIL_TOKEN_USED', '3x0000000000000000000000000000000AA');
$verifyUrl = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
$siteKey = SITE_TEST_KEY_ALWAYS_PASS_VISIBLE;
$secretKey = SECRET_TEST_KEY_ALWAYS_PASS;
$cookieName = 'turnstile_verified';
$cookieExpiration = 60; // verified for 1 minute
$cookie = isset($_COOKIE[$cookieName]) ? $_COOKIE[$cookieName] : false;
$hmacSecret = 'REPLACE_THIS_WITH_A_VERY_LONG_STRING_OF_RANDOM_CHARACTERS';
$isVerified = false;
$isSubmitted = $_SERVER['REQUEST_METHOD'] === 'POST';
$pageUrl = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$pageUrl = sprintf('%s?_=%d', $pageUrl, time());
if ($isSubmitted) {
$response = isset($_POST['cf-turnstile-response']) ? $_POST['cf-turnstile-response'] : '';
$data = http_build_query([
'secret' => $secretKey,
'response' => $response,
'remoteip' => $_SERVER['REMOTE_ADDR'],
]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $verifyUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // local dev only
$result = curl_exec($ch);
if ($result === false) {
print('<pre>');
printf('<a href="%s">Home</a>', $pageUrl);print(PHP_EOL);
print('<hr/>');
var_dump($response);print(PHP_EOL);
print(curl_errno($ch));print(PHP_EOL);
print(curl_error($ch));print(PHP_EOL);
print('</pre>');
die();
} else {
$json = json_decode($result, true);
if (isset($json['success']) && $json['success']) {
$expiration = time() + $cookieExpiration;
$payload = $expiration;
$hmac = hash_hmac('sha256', $payload, $hmacSecret);
$cookie = base64_encode($payload . ':' . $hmac);
setcookie($cookieName, $cookie, $expiration, "/");
$isVerified = true;
}
}
curl_close($ch);
} elseif ($cookie !== false) {
$cookie = base64_decode($cookie);
if ($cookie !== false) {
list($expiration, $hmac) = explode(':', $cookie);
$calculatedHmac = hash_hmac('sha256', $expiration, $hmacSecret);
if ($expiration >= time() && hash_equals($calculatedHmac, $hmac)) {
$isVerified = true;
}
}
}
?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple Cloudflare Turnstile Demo</title>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
</head>
<body>
<a href="<?php echo $pageUrl; ?>">Home</a>
<?php if ($isVerified): ?>
<p>Congratulations, you are verified!</p>
<?php else: ?>
<?php if ($isSubmitted): ?>
<p>Sorry, verification failed.</p>
<?php endif; ?>
<form method="post" action="<?php echo $pageUrl; ?>">
<div class="cf-turnstile" data-sitekey="<?php echo $siteKey; ?>"></div>
<br/>
<input type="submit">
</form>
<?php endif; ?>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment