080a160c7b9595d516c9c70e83689a09b60839d0 galt Mon Jun 3 12:16:53 2013 -0700 fix SQL Injection diff --git src/hg/lib/cart.c src/hg/lib/cart.c index b8401a1..7ddaf66 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -49,34 +49,34 @@ void cartTrace(struct cart *cart, char *when, struct sqlConnection *conn) /* Write some properties of the cart to stderr for debugging. */ { if (cfgOption("cart.trace") == NULL) return; struct cartDb *u = cart->userInfo, *s = cart->sessionInfo; char *pix = hashFindVal(cart->hash, "pix"); char *textSize = hashFindVal(cart->hash, "textSize"); char *trackControls = hashFindVal(cart->hash, "trackControlsOnMain"); int uLen, sLen; if (conn != NULL) { /* Since the content string is chopped, query for the actual length. */ char query[1024]; - safef(query, sizeof(query), "select length(contents) from userDb " + sqlSafef(query, sizeof(query), "select length(contents) from userDb " "where id = %d", u->id); uLen = sqlQuickNum(conn, query); - safef(query, sizeof(query), "select length(contents) from sessionDb " + sqlSafef(query, sizeof(query), "select length(contents) from sessionDb " "where id = %d", s->id); sLen = sqlQuickNum(conn, query); } else { uLen = strlen(u->contents); sLen = strlen(s->contents); } if (pix == NULL) pix = "-"; if (textSize == NULL) textSize = "-"; if (trackControls == NULL) trackControls = "-"; fprintf(stderr, "ASH: %22s: " @@ -164,87 +164,87 @@ } freez(&fu); return isCorr; } } struct cartDb *cartDbLoadFromId(struct sqlConnection *conn, char *table, int id) /* Load up cartDb entry for particular ID. Returns NULL if no such id. */ { if (id == 0) return NULL; else { struct cartDb *cdb = NULL; char where[64]; - safef(where, sizeof(where), "id = %u", id); + sqlSafefFrag(where, sizeof(where), "id = %u", id); cdb = cartDbLoadWhere(conn, table, where); if (looksCorrupted(cdb)) { /* Can't use warn here -- it interrupts the HTML header, causing an * err500 (and nothing useful in error_log) instead of a warning. */ fprintf(stderr, "%s id=%d looks corrupted -- starting over with new %s id.\n", table, id, table); cdb = NULL; } return cdb; } } struct cartDb *loadDb(struct sqlConnection *conn, char *table, int id, boolean *found) /* Load bits from database and save in hash. */ { struct cartDb *cdb; char query[256]; boolean result = TRUE; cdb = cartDbLoadFromId(conn, table, id); if (!cdb) { result = FALSE; - safef(query, sizeof(query), "INSERT %s VALUES(0,\"\",0,now(),now(),0)", + sqlSafef(query, sizeof(query), "INSERT %s VALUES(0,\"\",0,now(),now(),0)", table); sqlUpdate(conn, query); id = sqlLastAutoId(conn); if ((cdb = cartDbLoadFromId(conn,table,id)) == NULL) errAbort("Couldn't get cartDb for id=%d right after loading. " "MySQL problem??", id); } *found = result; return cdb; } void cartExclude(struct cart *cart, char *var) /* Exclude var from persistent storage. */ { hashAdd(cart->exclude, var, NULL); } void sessionTouchLastUse(struct sqlConnection *conn, char *encUserName, char *encSessionName) /* Increment namedSessionDb.useCount and update lastUse for this session. */ { struct dyString *dy = dyStringNew(1024); int useCount; -dyStringPrintf(dy, "SELECT useCount FROM %s " +sqlDyStringPrintf(dy, "SELECT useCount FROM %s " "WHERE userName = '%s' AND sessionName = '%s';", namedSessionTable, encUserName, encSessionName); useCount = sqlQuickNum(conn, dy->string) + 1; dyStringClear(dy); -dyStringPrintf(dy, "UPDATE %s SET useCount = %d, lastUse=now() " +sqlDyStringPrintf(dy, "UPDATE %s SET useCount = %d, lastUse=now() " "WHERE userName = '%s' AND sessionName = '%s';", namedSessionTable, useCount, encUserName, encSessionName); sqlUpdate(conn, dy->string); dyStringFree(&dy); } #ifndef GBROWSE void cartCopyCustomTracks(struct cart *cart) /* If cart contains any live custom tracks, save off a new copy of them, * to prevent clashes by multiple uses of the same session. */ { struct hashEl *el, *elList = hashElListHash(cart->hash); for (el = elList; el != NULL; el = el->next) { @@ -426,31 +426,31 @@ * If non-NULL, actionVar is a cartRemove wildcard string specifying the * CGI action variable that sent us here. */ { struct sqlResult *sr = NULL; char **row = NULL; char *userName = wikiLinkUserName(); char *encSessionName = cgiEncodeFull(sessionName); char *encSessionOwner = cgiEncodeFull(sessionOwner); char query[512]; if (isEmpty(sessionOwner)) errAbort("Please go back and enter a wiki user name for this session."); if (isEmpty(sessionName)) errAbort("Please go back and enter a session name to load."); -safef(query, sizeof(query), "SELECT shared, contents FROM %s " +sqlSafef(query, sizeof(query), "SELECT shared, contents FROM %s " "WHERE userName = '%s' AND sessionName = '%s';", namedSessionTable, encSessionOwner, encSessionName); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) != NULL) { boolean shared = atoi(row[0]); if (shared || (userName && sameString(sessionOwner, userName))) { char *sessionVar = cartSessionVarName(); unsigned hgsid = cartSessionId(cart); struct sqlConnection *conn2 = hConnectCentral(); sessionTouchLastUse(conn2, encSessionOwner, encSessionName); cartRemoveLike(cart, "*"); cartParseOverHash(cart, row[1]); @@ -654,34 +654,34 @@ while ((ex = *exclude++)) cartExclude(cart, ex); } cartDefaultDisconnector(&conn); return cart; } static void updateOne(struct sqlConnection *conn, char *table, struct cartDb *cdb, char *contents, int contentSize) /* Update cdb in database. */ { struct dyString *dy = newDyString(4096); -dyStringPrintf(dy, "UPDATE %s SET contents='", table); -dyStringAppendN(dy, contents, contentSize); -dyStringPrintf(dy, "',lastUse=now(),useCount=%d ", cdb->useCount+1); -dyStringPrintf(dy, " where id=%u", cdb->id); +sqlDyStringPrintf(dy, "UPDATE %s SET contents='", table); +sqlDyAppendEscaped(dy, contents); +sqlDyStringPrintf(dy, "',lastUse=now(),useCount=%d ", cdb->useCount+1); +sqlDyStringPrintf(dy, " where id=%u", cdb->id); sqlUpdate(conn, dy->string); dyStringFree(&dy); } void cartEncodeState(struct cart *cart, struct dyString *dy) /* Add a CGI-encoded var=val&... string of all cart variables to dy. */ { struct hashEl *el, *elList = hashElListHash(cart->hash); boolean firstTime = TRUE; char *s = NULL; for (el = elList; el != NULL; el = el->next) { if (!hashLookup(cart->exclude, el->name)) { @@ -1330,31 +1330,31 @@ return (hguidString == NULL ? 0 : atoi(hguidString)); } static int getSessionId() /* Get session id if any from CGI. */ { return cgiUsualInt("hgsid", 0); } static void clearDbContents(struct sqlConnection *conn, char *table, unsigned id) /* Clear out contents field of row in table that matches id. */ { char query[256]; if (id == 0) return; -safef(query, sizeof(query), "update %s set contents='' where id=%u", +sqlSafef(query, sizeof(query), "update %s set contents='' where id=%u", table, id); sqlUpdate(conn, query); } void cartResetInDb(char *cookieName) /* Clear cart in database. */ { int hguid = getCookieId(cookieName); int hgsid = getSessionId(); struct sqlConnection *conn = cartDefaultConnector(); clearDbContents(conn, "userDb", hguid); clearDbContents(conn, "sessionDb", hgsid); cartDefaultDisconnector(&conn); } @@ -1674,37 +1674,37 @@ char *chp; struct sqlConnection *conn, *conn2; conn= hAllocConn(genomeDb); conn2= hAllocConn(genomeDb); trashDirFile(&tn, "ct", "gsidSubj", ".list"); outName = tn.forCgi; trashDirFile(&tn2, "ct", "gsidSeq", ".list"); outName2 = tn2.forCgi; outF = mustOpen(outName,"w"); outF2= mustOpen(outName2,"w"); -safef(query, sizeof(query), "select distinct subjId from hgFixed.gsIdXref order by subjId"); +sqlSafef(query, sizeof(query), "select distinct subjId from hgFixed.gsIdXref order by subjId"); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { fprintf(outF, "%s\n", row[0]); - safef(query2, sizeof(query2), + sqlSafef(query2, sizeof(query2), "select dnaSeqId from hgFixed.gsIdXref where subjId='%s' order by dnaSeqId", row[0]); sr2 = sqlGetResult(conn2, query2); while ((row2 = sqlNextRow(sr2)) != NULL) { /* Remove "ss." from the front of the DNA sequence ID, so that they could be used both for DNA and protein MSA maf display */ chp = strstr(row2[0], "ss."); if (chp != NULL) { fprintf(outF2, "%s\t%s\n", chp+3L, row[0]); } else { fprintf(outF2, "%s\t%s\n", row2[0], row[0]); @@ -1784,32 +1784,32 @@ { errAbort("can't find species list file var '%s' in cart\n",speciesUseFile); } } struct lineFile *lf = lineFileOpen(val, TRUE); if (lf == NULL) errAbort("can't open species list file %s",val); if (hIsGsidServer()) { conn= hAllocConn(genomeDb); while( ( lineFileChopNext(lf, words, sizeof(words)/sizeof(char *)) )) { - safef(query, sizeof(query), - "select id from %s where id like '%s%s'", msaTable, "%", words[0]); + sqlSafef(query, sizeof(query), + "select id from %s where id like '%%%s'", msaTable, sqlCheckAlphaNum(words[0])); sr = sqlGetResult(conn, query); if (sqlNextRow(sr) != NULL) { dyStringPrintf(orderDY, "%s ",words[0]); sqlFreeResult(&sr); } } hFreeConn(&conn); } else { while( ( lineFileChopNext(lf, words, sizeof(words)/sizeof(char *)) )) { dyStringPrintf(orderDY, "%s ",words[0]); }