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/sortGenes.c src/hg/hgGenome/sortGenes.c
index 9a159ad8207..d1ed05220f3 100644
--- src/hg/hgGenome/sortGenes.c
+++ src/hg/hgGenome/sortGenes.c
@@ -1,23 +1,24 @@
 /* Sort Genes - handle click on sort genes button. Set up 
  * things so can go to gene sorter on genes inside regions
  * over threshold. */
 
 /* Copyright (C) 2013 The Regents of the University of California 
  * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
 
 #include "common.h"
+#include "htmshell.h"
 #include "hash.h"
 #include "portable.h"
 #include "jksql.h"
 #include "bed.h"
 #include "cheapcgi.h"
 #include "chromGraph.h"
 #include "binRange.h"
 #include "hdb.h"
 #include "hPrint.h"
 #include "../near/hgNear/hgNear.h"
 #include "hgGenome.h"
 #include "trashDir.h"
 
 
 struct colTrack
@@ -164,38 +165,38 @@
 
     }
 
 /* Get list of all transcripts in regions. */
 struct hashEl *el, *list = hashElListHash(transcriptHash);
 
 /* Create file with all matching gene IDs. */
 struct tempName keyTn;
 trashDirFile(&keyTn, "hgg", "key", ".key");
 FILE *f = mustOpen(keyTn.forCgi, "w");
 for (el = list; el != NULL; el = el->next)
     fprintf(f, "%s\n", el->name);
 carefulClose(&f);
 
 /* Print out some info. */
-hPrintf("Thresholding <i>%s</i> at %g. ", gg->shortLabel, threshold);
+hPrintf("Thresholding <i>%s</i> at %g. ", htmlEncode(gg->shortLabel), threshold); // user graph label, escape (XSS)
 hPrintf("There are %d regions covering %lld bases.<BR>\n",
     slCount(bedList), bedTotalSize((struct bed*)bedList) );
 hPrintf("Installed a Gene Sorter filter that selects only genes in these regions.<BR>\n");
 if (m)
     {
     hPrintf("There are %d markers in the regions over threshold that overlap knownGenes.<BR>\n", markerCount);
-    hPrintf("Installed a Gene Sorter custom column called \"%s Markers\" with these markers.<BR>\n", gg->shortLabel);
+    hPrintf("Installed a Gene Sorter custom column called \"%s Markers\" with these markers.<BR>\n", htmlEncode(gg->shortLabel));
     }
 
 /* close custom column output file */
 if (m)
     {
     lineFileClose(&m);
     carefulClose(&g);
     }
 
 /* Stuff cart variable with name of file. */
 char keyCartName[256];
 safef(keyCartName, sizeof(keyCartName), "%s%s.keyFile",
 	advFilterPrefix, idColumn);
 cartSetString(cart, keyCartName, keyTn.forCgi);