80f55de280d3cc483b772c1d02dd88b6bc1cf173 max Thu Oct 16 03:01:55 2025 -0700 adding an apache logfile line when apiKey is recognized, refs #36428 diff --git src/hg/lib/cart.c src/hg/lib/cart.c index 14cd37aee1b..f53e0c2c84f 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -1470,30 +1470,31 @@ { 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 = strstr(reply, "\"success\":true") != NULL; freez(&reply); return res; } +// hg.conf key with the cloud flare secret key, used twice here, so a global macro #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("<html><head>"); puts("<script>"); printf("function showWidget() { \n" "turnstile.render('#myWidget', {\n" "sitekey: '%s',\n" @@ -1553,45 +1554,45 @@ return; captchaCheckDone = TRUE; if (fromCommandLine || isEmpty(cfgOption(CLOUDFLARESITEKEY))) return; // no captcha for our own QA scripts running on a server with our IP address if (botException()) return; // certain user agents are allowed to use the website without a captcha if (isUserAgentException()) return; -// a valid apiKey can always be used to get around the captcha. Note that bottlenecking is then done on the level +char *cgi = cgiScriptName(); + +// An apiKey can always be used to get around the captcha. Note that bottlenecking is then done on the level // of the apiKey, if a valid apiKey has been supplied, see botDelay.c, so the check if the apiKey is valid is assumed -// to have been done at the bottleneck step +// to have been done at the bottleneck step, which in all our CGIs is called before the cart is initialized. char *apiKey = cgiOptionalString("apiKey"); if (apiKey) { - // This assumes that we've checked the API key already in botdelay.c. All our CGIs - // call botDelay, we assume that botDelay has been called. + fprintf(stderr, "CAPTCHAPASS_APIKEY %s %s\n", apiKey, cgi); return; } // hgRenderTracks should not show the captcha - it was made to be used from other websites // For hgSession, we redirect from euro and asia to the RR - avoid showing the captcha there // hgLogin is the redirect target for hgSession, so avoid it there as well -char *cgi = cgiScriptName(); if ( sameWord(cgi, "/cgi-bin/hgRenderTracks") || sameWord(cgi, "/cgi-bin/hgSession") || sameWord(cgi, "/cgi-bin/hgLogin") ) 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) { if (isValidToken(token))