|
|
|
@@ -0,0 +1,48 @@ |
|
|
|
<% |
|
|
|
'======================================================================================================================= |
|
|
|
' Cloudflare Turnstile (CAPTCHA) server-side verification |
|
|
|
'======================================================================================================================= |
|
|
|
' Verifies a Turnstile response token against Cloudflare's siteverify endpoint. Unlike |
|
|
|
' JurisdictionValidator's fail-open behavior (missing reference data shouldn't block orders), |
|
|
|
' this fails CLOSED: a missing token or a failed/unreachable verification call is treated as |
|
|
|
' "not verified" rather than being let through, since the whole point is to block automated |
|
|
|
' submissions. |
|
|
|
'======================================================================================================================= |
|
|
|
|
|
|
|
Const TURNSTILE_VERIFY_URL = "https://challenges.cloudflare.com/turnstile/v0/siteverify" |
|
|
|
|
|
|
|
' Verifies a Turnstile response token (the value of the widget's "cf-turnstile-response" |
|
|
|
' field / the token returned to the data-callback). remoteIp is optional - pass "" to omit it. |
|
|
|
Function VerifyTurnstileToken(responseToken, remoteIp) |
|
|
|
VerifyTurnstileToken = False |
|
|
|
|
|
|
|
responseToken = Trim(responseToken) |
|
|
|
If Len(responseToken) = 0 Then Exit Function |
|
|
|
|
|
|
|
Dim secretKey : secretKey = GetAppSetting("TurnstileSecretKey") |
|
|
|
If Len(secretKey) = 0 Then Exit Function |
|
|
|
|
|
|
|
Dim body |
|
|
|
body = "secret=" & Server.URLEncode(secretKey) & "&response=" & Server.URLEncode(responseToken) |
|
|
|
If Len(remoteIp) > 0 Then body = body & "&remoteip=" & Server.URLEncode(remoteIp) |
|
|
|
|
|
|
|
On Error Resume Next |
|
|
|
|
|
|
|
Dim http : Set http = Server.CreateObject("Msxml2.ServerXMLHTTP") |
|
|
|
http.setTimeouts 5000, 5000, 5000, 5000 |
|
|
|
http.Open "POST", TURNSTILE_VERIFY_URL, False |
|
|
|
http.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" |
|
|
|
http.Send body |
|
|
|
|
|
|
|
If Err.Number = 0 And http.Status = 200 Then |
|
|
|
Dim re |
|
|
|
Set re = New RegExp |
|
|
|
re.Pattern = """success""\s*:\s*true" |
|
|
|
re.IgnoreCase = True |
|
|
|
VerifyTurnstileToken = re.Test(http.responseText) |
|
|
|
End If |
|
|
|
|
|
|
|
Err.Clear |
|
|
|
On Error GoTo 0 |
|
|
|
End Function |
|
|
|
%> |