a1d7c07c50f1d895337de121680ea672b261c058 max Mon Aug 17 02:26:36 2026 -0700 escape reflected/echoed user input across several CGIs (XSS), refs #38057 Route user-, DB- and hub-derived values through htmlEncode (HTML/attribute text), cgiEncode (values composed into URLs), jsonStringEscape (values placed in a JS string literal inside an inline script) or, for hgMirror, the existing mustBeClean sanitizer. Covers hgHubConnect, hgUserSuggestion, hgLiftOver, hgBlat, hgc pubs, hgVisiGene, hgSession, hgTrackUi, hgGenome, phyloPng, hgFileSearch, hgLinkIn, hgPal, hui, hgPhyloPlace, hgMirror, hgCustom and hgSearch. diff --git src/hg/hgGenome/browseRegions.c src/hg/hgGenome/browseRegions.c index 5d056c9016d..02ec7a4d039 100644 --- src/hg/hgGenome/browseRegions.c +++ src/hg/hgGenome/browseRegions.c @@ -1,72 +1,72 @@ /* Copyright (C) 2012 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #include "common.h" #include "hash.h" #include "portable.h" #include "bed.h" #include "htmshell.h" #include "cart.h" #include "hui.h" #include "web.h" #include "chromGraph.h" #include "hPrint.h" #include "hgGenome.h" #include "trashDir.h" static void quotedBrowserUrl(FILE *f, struct bed3 *bed, struct genoGraph *gg) /* Print URL that will open browser at bed position with genoGraph track on */ { fprintf(f, "\"../../cgi-bin/hgTracks?db=%s&position=%s:%d-%d&hgGenomeClick=browseRegions&%s=full\"", database, bed->chrom, bed->chromStart+1, bed->chromEnd, gg->name); } void browseRegions(struct sqlConnection *conn) /* Put up a frame with a list of links on the left and the * first link selected on the right. */ { struct genoGraph *gg = ggFirstVisible(); double threshold = getThreshold(); struct bed3 *bed, *bedList = regionsOverThreshold(gg); /* Define names of our two frames. */ char *browserFrame = "browser"; char *indexFrame = "index"; /* Write index html file. */ struct tempName indexTn; trashDirFile(&indexTn, "hgg", "index", ".html"); FILE *f = mustOpen(indexTn.forCgi, "w"); htmStart(f, "Region Index"); fprintf(f, "<BODY>"); -fprintf(f, "<B>%s</B><BR>\n", gg->shortLabel); +fprintf(f, "<B>%s</B><BR>\n", htmlEncode(gg->shortLabel)); // user graph label, escape (XSS) fprintf(f, "%3.1f Mb in<BR>\n", 0.000001*bedTotalSize((struct bed*)bedList)); fprintf(f, "%d regions > %g<BR>\n", slCount(bedList), threshold); for (bed = bedList; bed != NULL; bed = bed->next) { fprintf(f, "<A HREF="); quotedBrowserUrl(f, bed, gg); fprintf(f, " TARGET=\"%s\">", browserFrame); fprintf(f, "%s %3.1fM to %3.1fM</A><BR>", bed->chrom, 0.000001*bed->chromStart, 0.000001*bed->chromEnd); } fprintf(f, "</BODY>\n"); carefulClose(&f); /* Write frames */ hPrintf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\">\n"); hPrintf("<HTML><HEAD>\n%s<TITLE>%s Regions >= %g</TITLE></HEAD>\n", - getCspMetaHeader(), gg->shortLabel, threshold); + getCspMetaHeader(), htmlEncode(gg->shortLabel), threshold); hPrintf("<FRAMESET COLS=\"19%%,81%%\">\n"); hPrintf("<FRAME SRC=\"%s\" NAME=\"%s\">\n", indexTn.forCgi, indexFrame); hPrintf("<FRAME SRC="); quotedBrowserUrl(stdout, bedList, gg); hPrintf(" NAME=\"%s\">\n", browserFrame); hPrintf("<NOFRAMES><BODY></BODY></NOFRAMES>\n"); hPrintf("</FRAMESET>\n"); hPrintf("</HTML>\n"); }