ca99897a163f545419d58c22e594d9608474cdb7
jcasper
  Tue Jun 9 19:10:23 2026 -0700
Moving sessionDb load after captcha check so bot traffic doesn't fill up sessionDb, refs #37739

diff --git src/hg/lib/cart.c src/hg/lib/cart.c
index dfefd94fd91..d72867b30bb 100644
--- src/hg/lib/cart.c
+++ src/hg/lib/cart.c
@@ -1672,35 +1672,36 @@
 {
 genericCgiSetup();
 
 struct cart *cart;
 struct sqlConnection *conn = cartDefaultConnector();
 char *ex;
 boolean userIdFound = FALSE, sessionIdFound = FALSE;
 
 AllocVar(cart);
 cart->hash = newHash(12);
 cart->exclude = newHash(7);
 cart->userId = userId;
 cart->sessionId = sessionId;
 cart->userInfo = loadDb(conn, userDbTable(), userId, &userIdFound);
 
-cart->sessionInfo = loadDb(conn, sessionDbTable(), sessionId, &sessionIdFound);
-
 boolean fromCli = cgiWasSpoofed(); // QA runs our CGIs from the command line and we debug from there
 
 forceUserIdOrCaptcha(cart, userId, userIdFound, fromCli);
+// Load sessionDb info *after* forceUserIdOrCaptcha.  loadDb will create a new record if it doesn't
+// find a matching one, and we don't need bot traffic filling our sessionDb table with junk.
+cart->sessionInfo = loadDb(conn, sessionDbTable(), sessionId, &sessionIdFound);
 
 // we rely on the cookie being validated, so if we reset a cookie, do this after the captcha
 if ( cgiOptionalString("ignoreCookie") != NULL )
     cart->userInfo = loadDb(conn, userDbTable(), NULL, &userIdFound);
 
 if (sessionIdFound)
     cartParseOverHash(cart, cart->sessionInfo->contents);
 else if (userIdFound)
     cartParseOverHash(cart, cart->userInfo->contents);
 else
     {
     char *defaultCartContents = getDefaultCart(conn);
     cartParseOverHash(cart, defaultCartContents);
     }
 char when[1024];