f95037b8f6bb5cad8f0cbd16067e4ebc8cdecaf9 max Mon Jul 14 12:00:52 2025 -0700 fixing captcha problem, refs #36057 diff --git src/hg/lib/cart.c src/hg/lib/cart.c index 8c9c9195e56..a12d1a9b6b1 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -1460,31 +1460,31 @@ } } boolean isValidToken(char *token) /* send https req to cloudflare, check if the token that we got from the captcha is really the one made by cloudflare */ { char *url = "https://challenges.cloudflare.com/turnstile/v0/siteverify"; char *secret = cfgVal("cloudFlareSecretKey"); if (!secret) errAbort("'cloudFlareSecretKey' must be set in hg.conf if cloudflare is activated in hg.conf"); char data[3000]; // cloudflare token is at most 2000 bytes safef(data, sizeof(data), "secret=%s&response=%s", secret, token); char *reply = curlPostUrl(url, data); - boolean res = startsWith("{\"success\":true", reply); + boolean res = strstr(reply, "\"success\":true") != NULL; freez(&reply); return res; } #define CLOUDFLARESITEKEY "cloudFlareSiteKey" void printCaptcha() /* print an html page that shows the captcha and on success, reloads the page with the token added as token=x */ { char *cfSiteKey = cfgVal(CLOUDFLARESITEKEY); if (!cfSiteKey) return; puts("Content-Type:text/html\n"); // puts outputs one newline. Header requires two newlines. puts(""); @@ -1556,35 +1556,50 @@ return; // certain user agents are allowed to use the website without a captcha if (isUserAgentException()) return; // Do not show a captcha if we have a valid cookie // but for debugging, it's nice to be able to force the captcha if (userId && userIdFound && !cgiOptionalString("captcha")) return; // when the captcha is solved, our JS code does a full page-reload, no AJAX. That saves us one round-trip. // After the reload, the new page URL has the captcha token in the URL argument list, so now we need to validate it // and remove it from the cart char *token = cgiOptionalString("token"); -if (token && isValidToken(token)) +if (token) +{ + if (isValidToken(token)) { cartRemove(cart, "token"); return; } + else + { + puts("Content-Type: text/html\n"); + puts("Internal captcha error: Cloudflare rejected the captcha token. " + "Something is not working internally, we are very sorry. You can try reloading the page. " + "If this problem persists, send an email to genome-www@soe.ucsc.edu and we will " + "look into it as quickly as we can in the PST timezone. You can use any internet browser " + "where you have used the genome browser before, but not from this internet browser. " + "You can try our mirror sites, " + "genome-euro.ucsc.edu or genome-asia.ucsc.edu, while we are working on a solution."); + exit(0); + } +} printCaptcha(); } void cartRemove(struct cart *cart, char *var); static void genericCgiSetup() /* Run steps that all CGIs must do that unrelated to the cart: timeout, logging setup, UDC. */ { static boolean genericSetupDone = FALSE; // do this only once per execution if (genericSetupDone) return;