Created
February 4, 2026 07:13
-
-
Save opentechnologist/42d5a8ae9a71196c2384082e53fd246b to your computer and use it in GitHub Desktop.
a simple php script to determine if turnstile setup is working properly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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