304e190d0af4be54569ac20edc26999673c44f8b braney Tue Aug 18 11:05:19 2026 -0700 hgTrackUi, hui: encode trackDb-derived label text consistently, refs #38123 diff --git src/hg/hgTrackUi/hgTrackUi.c src/hg/hgTrackUi/hgTrackUi.c index 4a883081e32..e664821afe3 100644 --- src/hg/hgTrackUi/hgTrackUi.c +++ src/hg/hgTrackUi/hgTrackUi.c @@ -3917,32 +3917,34 @@ "(All %s%s)", hgTracksName(), cartSessionVarName(), cartSessionId(cart),database,chromosome, tdb->grp,tdb->grp,grp->label,grp->label, endsWith(grp->label," Tracks")?"":" tracks"); break; } } grpFreeList(&grps); } // incoming links from Google searches can go directly to a composite child trackUi page: tell users // that they're inside a container now and can go back up the hierarchy if (tdbGetComposite(tdb)) { - printf("

This track is a subtrack of the composite container track \"%s\".
", tdb->parent->shortLabel); - printf("Click here to display the \"%s\" container configuration page.", database, chromosome, tdb->parent->track, tdb->parent->shortLabel); + // shortLabel comes from trackDb, which a track hub controls, escape + printf("

This track is a subtrack of the composite container track \"%s\".
", + htmlEncode(tdb->parent->shortLabel)); + printf("Click here to display the \"%s\" container configuration page.", database, chromosome, tdb->parent->track, htmlEncode(tdb->parent->shortLabel)); } } puts("

"); if (tdbIsSuperTrackChild(tdb)) showSupertrackInfo(tdb); if (ct && sameString(tdb->type, "maf")) tdb->canPack = TRUE; else if (sameString(tdb->track, WIKI_TRACK_TABLE)) // special case wikiTrack (there's no trackDb entry); fixes redmine 2395 tdb->canPack = TRUE; else if (sameString(tdb->type, "halSnake")) @@ -4604,47 +4606,49 @@ tdb = dupTdbFrom(tdb, dup); } if(cartOptionalString(cart, "ajax")) { // html is going to be used w/n a dialog in hgTracks.js so serve up stripped down html // still need CSP2 header for security printf("%s", getCspMetaHeader()); trackUi(tdb, tdbList, ct, TRUE); cartRemove(cart,"ajax"); jsInlineFinish(); } else { - char title[1000]; + // htmlNoEscape() below lets the through, so the labels themselves have to be + // escaped here - they come from trackDb, which a track hub controls + struct dyString *title = dyStringNew(0); if (tdb->parent) { - safef(title, sizeof title, + dyStringPrintf(title, // TODO: replace in-line styling with class "" "%s %s", - tdb->parent->shortLabel, tdb->shortLabel); + htmlEncode(tdb->parent->shortLabel), htmlEncode(tdb->shortLabel)); } else - safef(title, sizeof title, "%s", tdb->shortLabel); + dyStringPrintf(title, "%s", htmlEncode(tdb->shortLabel)); char *titleEnd = (tdbIsSuper(tdb) ? "Tracks" : tdbIsDownloadsOnly(tdb) ? DOWNLOADS_ONLY_TITLE : "Track Settings"); htmlNoEscape(); // allow HTML tags to format title blue bar (using short label) - cartWebStart(cart, database, "%s %s", title, titleEnd); + cartWebStart(cart, database, "%s %s", title->string, titleEnd); htmlDoEscape(); trackUi(tdb, tdbList, ct, FALSE); printf("
\n"); jsonPrintGlobals(); webEnd(); } } char *excludeVars[] = { "submit", "Submit", "g", "fileUrl", "track", "sourceDb", NULL, "ajax", NULL,}; int main(int argc, char *argv[]) /* Process command line. */ { long enteredMainTime = clock1000(); /* 0, 0, == use default 10 second for warning, 20 second for immediate exit */