From c7687ee27fee19ad2b5b50934e8d06d37bc7cece Mon Sep 17 00:00:00 2001 From: Daniel Covington Date: Tue, 18 Aug 2026 13:22:40 -0400 Subject: [PATCH] Added capcha --- app/controllers/OrderApiController.asp | 6 +++ app/controllers/OrderController.asp | 3 +- app/controllers/RequestOrderController.asp | 8 +++- app/controllers/autoload_controllers.asp | 1 + app/models/TurnstileValidator.asp | 48 ++++++++++++++++++++++ app/views/Order/continue.asp | 21 +++++++++- app/views/RequestOrder/index.asp | 4 ++ public/web.config | 7 ++++ widget | 2 + 9 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 app/models/TurnstileValidator.asp create mode 100644 widget diff --git a/app/controllers/OrderApiController.asp b/app/controllers/OrderApiController.asp index efaa0e6..890fb56 100644 --- a/app/controllers/OrderApiController.asp +++ b/app/controllers/OrderApiController.asp @@ -66,6 +66,12 @@ Class OrderApiController_Class Exit Sub End If + Dim turnstileToken : turnstileToken = Request.ServerVariables("HTTP_X_TURNSTILE_TOKEN") + If Not VerifyTurnstileToken(turnstileToken, Request.ServerVariables("REMOTE_ADDR")) Then + WriteJsonError "403 Forbidden", "Verification challenge failed. Please refresh the page and try again." + Exit Sub + End If + Dim answers On Error Resume Next json().loadJSON GetRawJsonFromRequest() diff --git a/app/controllers/OrderController.asp b/app/controllers/OrderController.asp index 518d0da..c83e00c 100644 --- a/app/controllers/OrderController.asp +++ b/app/controllers/OrderController.asp @@ -29,11 +29,12 @@ Class OrderController_Class ' The order form itself is a placeholder for now - this only confirms the token is valid. '------------------------------------------------------------------------------------------------------------------- Public Sub Continue() - Dim token, order, isValid, csrfToken, municipalityName + Dim token, order, isValid, csrfToken, municipalityName, turnstileSiteKey token = Trim(Request.QueryString("token")) isValid = False csrfToken = "" municipalityName = "" + turnstileSiteKey = GetAppSetting("TurnstileSiteKey") Set order = Nothing If Len(token) > 0 Then diff --git a/app/controllers/RequestOrderController.asp b/app/controllers/RequestOrderController.asp index 51dca08..b33e684 100644 --- a/app/controllers/RequestOrderController.asp +++ b/app/controllers/RequestOrderController.asp @@ -28,7 +28,7 @@ Class RequestOrderController_Class ' GET: show the "request an order" form (email + jurisdiction number) '------------------------------------------------------------------------------------------------------------------- Public Sub Index() - Dim formValues, emailValue, jurisdictionValue, csrfToken + Dim formValues, emailValue, jurisdictionValue, csrfToken, turnstileSiteKey Set formValues = FormCache().DeserializeForm("RequestOrder") FormCache().ClearForm "RequestOrder" @@ -41,6 +41,7 @@ Class RequestOrderController_Class End If csrfToken = HTMLSecurity().GetAntiCSRFToken("RequestOrder") + turnstileSiteKey = GetAppSetting("TurnstileSiteKey") %> <% @@ -73,6 +74,11 @@ Class RequestOrderController_Class AddValidationError errorList, "That jurisdiction number could not be verified." End If + Dim turnstileToken : turnstileToken = Request.Form("cf-turnstile-response") + If Not VerifyTurnstileToken(turnstileToken, Request.ServerVariables("REMOTE_ADDR")) Then + AddValidationError errorList, "Please complete the verification challenge." + End If + If UBound(errorList) >= 0 Then Dim i For i = 0 To UBound(errorList) diff --git a/app/controllers/autoload_controllers.asp b/app/controllers/autoload_controllers.asp index 255211b..e70dc3b 100644 --- a/app/controllers/autoload_controllers.asp +++ b/app/controllers/autoload_controllers.asp @@ -1,5 +1,6 @@ + diff --git a/app/models/TurnstileValidator.asp b/app/models/TurnstileValidator.asp new file mode 100644 index 0000000..5866f80 --- /dev/null +++ b/app/models/TurnstileValidator.asp @@ -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 +%> diff --git a/app/views/Order/continue.asp b/app/views/Order/continue.asp index 53baf93..cd9064f 100644 --- a/app/views/Order/continue.asp +++ b/app/views/Order/continue.asp @@ -25,6 +25,12 @@ %> +
+
+
+