080a160c7b9595d516c9c70e83689a09b60839d0 galt Mon Jun 3 12:16:53 2013 -0700 fix SQL Injection diff --git src/hg/lib/wikiTrack.c src/hg/lib/wikiTrack.c index 6852a33..b17f3fb 100644 --- src/hg/lib/wikiTrack.c +++ src/hg/lib/wikiTrack.c @@ -110,80 +110,39 @@ while ((row = sqlNextRow(sr)) != NULL) { el = wikiTrackLoad(row); slAddHead(&list, el); } slReverse(&list); sqlFreeResult(&sr); return list; } void wikiTrackSaveToDb(struct sqlConnection *conn, struct wikiTrack *el, char *tableName, int updateSize) /* Save wikiTrack as a row to the table specified by tableName. * As blob fields may be arbitrary size updateSize specifies the approx size * of a string that would contain the entire query. Arrays of native types are * converted to comma separated strings and loaded as such, User defined types are - * inserted as NULL. Note that strings must be escaped to allow insertion into the database. - * For example "autosql's features include" --> "autosql\'s features include" - * If worried about this use wikiTrackSaveToDbEscaped() */ + * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */ { struct dyString *update = newDyString(updateSize); -dyStringPrintf(update, "insert into %s values ( %u,'%s',%u,%u,'%s',%u,'%s','%s','%s','%s','%s','%s','%s','%s',%u,'%s')", +sqlDyStringPrintf(update, "insert into %s values ( %u,'%s',%u,%u,'%s',%u,'%s','%s','%s','%s','%s','%s','%s','%s',%u,'%s')", tableName, el->bin, el->chrom, el->chromStart, el->chromEnd, el->name, el->score, el->strand, el->db, el->owner, el->color, el->class, el->creationDate, el->lastModifiedDate, el->descriptionKey, el->id, el->geneSymbol); sqlUpdate(conn, update->string); freeDyString(&update); } -void wikiTrackSaveToDbEscaped(struct sqlConnection *conn, struct wikiTrack *el, char *tableName, int updateSize) -/* Save wikiTrack as a row to the table specified by tableName. - * As blob fields may be arbitrary size updateSize specifies the approx size. - * of a string that would contain the entire query. Automatically - * escapes all simple strings (not arrays of string) but may be slower than wikiTrackSaveToDb(). - * For example automatically copies and converts: - * "autosql's features include" --> "autosql\'s features include" - * before inserting into database. */ -{ -struct dyString *update = newDyString(updateSize); -char *chrom, *name, *strand, *db, *owner, *color, *class, *creationDate, *lastModifiedDate, *descriptionKey, *geneSymbol; -chrom = sqlEscapeString(el->chrom); -name = sqlEscapeString(el->name); -strand = sqlEscapeString(el->strand); -db = sqlEscapeString(el->db); -owner = sqlEscapeString(el->owner); -color = sqlEscapeString(el->color); -class = sqlEscapeString(el->class); -creationDate = sqlEscapeString(el->creationDate); -lastModifiedDate = sqlEscapeString(el->lastModifiedDate); -descriptionKey = sqlEscapeString(el->descriptionKey); -geneSymbol = sqlEscapeString(el->geneSymbol); - -dyStringPrintf(update, "insert into %s values ( %u,'%s',%u,%u,'%s',%u,'%s','%s','%s','%s','%s','%s','%s','%s',%u,'%s')", - tableName, el->bin , chrom, el->chromStart , el->chromEnd , name, el->score , strand, db, owner, color, class, creationDate, lastModifiedDate, descriptionKey, el->id , geneSymbol); -sqlUpdate(conn, update->string); -freeDyString(&update); -freez(&chrom); -freez(&name); -freez(&strand); -freez(&db); -freez(&owner); -freez(&color); -freez(&class); -freez(&creationDate); -freez(&lastModifiedDate); -freez(&descriptionKey); -freez(&geneSymbol); -} struct wikiTrack *wikiTrackCommaIn(char **pS, struct wikiTrack *ret) /* Create a wikiTrack out of a comma separated string. * This will fill in ret if non-null, otherwise will * return a new wikiTrack */ { char *s = *pS; if (ret == NULL) AllocVar(ret); ret->bin = sqlUnsignedComma(&s); ret->chrom = sqlStringComma(&s); ret->chromStart = sqlUnsignedComma(&s); ret->chromEnd = sqlUnsignedComma(&s); ret->name = sqlStringComma(&s); @@ -305,31 +264,31 @@ #include "cart.h" #include "hPrint.h" #include "grp.h" #include "obscure.h" #include "hCommon.h" #include "web.h" #include "hgColors.h" #ifdef NOT static void savePosInTextBox(char *chrom, int start, int end) /* Save basic position/database info in text box and hidden var. Positions becomes chrom:start-end*/ { char position[128]; char *newPos; -snprintf(position, 128, "%s:%d-%d", chrom, start, end); +safef(position, 128, "%s:%d-%d", chrom, start, end); newPos = addCommasToPos(position); cgiMakeTextVar("getDnaPos", newPos, strlen(newPos) + 2); cgiContinueHiddenVar("db"); } #endif boolean wikiTrackReadOnly() /* return TRUE if wiki track is in Read-Only mode, default answer is FALSE */ { return cfgOptionBooleanDefault(CFG_WIKI_TRACK_READ_ONLY, FALSE); } boolean wikiTrackEnabled(char *database, char **wikiUserName) /*determine if wikiTrack can be used, and is this user logged into the wiki ?*/ { @@ -443,35 +402,35 @@ "class varchar(255) not null,\n" "creationDate varchar(255) not null,\n" "lastModifiedDate varchar(255) not null,\n" "descriptionKey varchar(255) not null,\n" "id int unsigned not null auto_increment,\n" "geneSymbol varchar(255) null,\n" "PRIMARY KEY(id),\n" "INDEX chrom (db,bin,chrom),\n" "INDEX name (db,name),\n" "INDEX gene (geneSymbol)\n" ")\n"; char *wikiTrackGetCreateSql(char *tableName) /* return sql create statement for wiki track with tableName */ { -struct dyString *createTable = dyStringNew(512); +struct dyString *dy = dyStringNew(512); -dyStringPrintf(createTable, createString, tableName); +sqlDyStringPrintf(dy, createString, tableName); -return (dyStringCannibalize(&createTable)); +return (dyStringCannibalize(&dy)); } char *wikiDbName() /* return name of database where wiki track is located currently this is central.db but the future may be configurable */ { static char *dbName = NULL; if (dbName) return dbName; char setting[64]; safef(setting, sizeof(setting), "central.db"); dbName = cfgOption(setting); return dbName; @@ -487,74 +446,74 @@ } void wikiDisconnect(struct sqlConnection **pConn) /* disconnect from wikiTrack table database */ { hDisconnectCentral(pConn); } struct wikiTrack *findWikiItemId(char *wikiItemId) /* given a wikiItemId return the row from the table */ { struct wikiTrack *item; char query[256]; struct sqlConnection *wikiConn = wikiConnect(); -safef(query, ArraySize(query), "SELECT * FROM %s WHERE id='%s' limit 1", +sqlSafef(query, ArraySize(query), "SELECT * FROM %s WHERE id='%s' limit 1", WIKI_TRACK_TABLE, wikiItemId); item = wikiTrackLoadByQuery(wikiConn, query); if (NULL == item) errAbort("display wiki item: failed to load item '%s'", wikiItemId); wikiDisconnect(&wikiConn); return item; } struct wikiTrack *findWikiItemByGeneSymbol(char *db, char *geneSymbol) /* given a db and UCSC known gene geneSymbol, find the wiki item */ { struct wikiTrack *item = NULL; /* make sure neither of these arguments is NULL */ if (db && geneSymbol) { char query[256]; struct sqlConnection *wikiConn = wikiConnect(); - safef(query, ArraySize(query), + sqlSafef(query, ArraySize(query), "SELECT * FROM %s WHERE db='%s' AND geneSymbol='%s' limit 1", WIKI_TRACK_TABLE, db, geneSymbol); item = wikiTrackLoadByQuery(wikiConn, query); wikiDisconnect(&wikiConn); } return item; } struct wikiTrack *findWikiItemByName(char *db, char *name) /* given a db,name pair return the row from the table, can return NULL */ { struct wikiTrack *item = NULL; /* make sure neither of these arguments is NULL */ if (name && db) { char query[256]; struct sqlConnection *wikiConn = wikiConnect(); - safef(query, ArraySize(query), + sqlSafef(query, ArraySize(query), "SELECT * FROM %s WHERE db='%s' AND name='%s' limit 1", WIKI_TRACK_TABLE, db, name); item = wikiTrackLoadByQuery(wikiConn, query); wikiDisconnect(&wikiConn); } return item; } static char *stripEditURLs(char *rendered) /* test for actual text, remove edit sections and any html comment strings */ { char *stripped = cloneString(rendered); @@ -802,31 +761,31 @@ char *userSignature; /* In the case where this is a restoration of the header lines, * may be a different creator than this user adding comments. * So, get the header line correct to represent the actual creator. */ if (sameWord(userName, item->owner)) userSignature = cloneString("~~~~"); else { struct dyString *tt = newDyString(1024); dyStringPrintf(tt, "[[User:%s|%s]] ", item->owner, item->owner); dyStringPrintf(tt, "%s", item->creationDate); userSignature = dyStringCannibalize(&tt); recreateHeader = TRUE; } - snprintf(position, 128, "%s:%d-%d", seqName, winStart+1, winEnd); + safef(position, 128, "%s:%d-%d", seqName, winStart+1, winEnd); newPos = addCommasToPos(database, position); if (extraHeader) { dyStringPrintf(content, "%s\n%s\n", category, extraHeader); } else { dyStringPrintf(content, "%s\n" "[http://%s/cgi-bin/hgTracks?db=%s&wikiTrack=pack&position=%s:%d-%d %s %s]" "  '%s'  ", category, cfgOptionDefault(CFG_WIKI_BROWSER, DEFAULT_BROWSER), database, seqName, winStart+1, winEnd, database, newPos, item->name); @@ -940,31 +899,31 @@ char *userSignature; /* In the case where this is a restoration of the header lines, * may be a different creator than this user adding comments. * So, get the header line correct to represent the actual creator. */ if (sameWord(userName, item->owner)) userSignature = cloneString("~~~~"); else { struct dyString *tt = newDyString(1024); dyStringPrintf(tt, "[[User:%s|%s]] ", item->owner, item->owner); dyStringPrintf(tt, "%s", item->creationDate); userSignature = dyStringCannibalize(&tt); recreateHeader = TRUE; } - snprintf(position, 128, "%s:%d-%d", seqName, winStart+1, winEnd); + safef(position, 128, "%s:%d-%d", seqName, winStart+1, winEnd); newPos = addCommasToPos(database, position); if (extraHeader) { dyStringPrintf(content, "%s\n%s\n", category, extraHeader); } else { dyStringPrintf(content, "%s\n" "[http://%s/cgi-bin/hgTracks?db=%s&wikiTrack=pack&position=%s:%d-%d %s %s]" "  '%s'  ", category, cfgOptionDefault(CFG_WIKI_BROWSER, DEFAULT_BROWSER), database, seqName, winStart+1, winEnd, database, newPos, item->name); }