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/import.c src/hg/hgGenome/import.c
index fa89e58611e..1a1ce26f369 100644
--- src/hg/hgGenome/import.c
+++ src/hg/hgGenome/import.c
@@ -1,21 +1,22 @@
 /* Import - put up import pages and sub-pages. */
 
 /* 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 "linefile.h"
 #include "hash.h"
 #include "ra.h"
 #include "portable.h"
 #include "cheapcgi.h"
 #include "localmem.h"
 #include "cart.h"
 #include "web.h"
 #include "chromInfo.h"
 #include "chromGraph.h"
 #include "chromGraphFactory.h"
 #include "errCatch.h"
 #include "hPrint.h"
 #include "customTrack.h"
 #include "trackDb.h"
@@ -595,31 +596,31 @@
     if (allTracks)
         {
         selTrack = findSelectedTrack(fullTrackList, NULL, trackVar);
         slSort(&fullTrackList, trackDbCmpShortLabel);
         }
     else
         {
         selTrack = findSelectedTrack(fullTrackList, selGroup, trackVar);
         }
     for (track = fullTrackList; track != NULL; track = track->next)
         {
         if (allTracks || sameString(selGroup->name, track->grp))
             {
             hPrintf(" <OPTION VALUE=\"%s\"%s>%s\n", (track->table?track->table:track->track),
                 (track == selTrack ? " SELECTED" : ""),
-                track->shortLabel);
+                htmlEncode(track->shortLabel)); // label in dropdown text, escape (XSS)
             }
         }
     hPrintf("</SELECT>\n");
     }
 hPrintf("\n");
 return selTrack;
 }
 
 
 struct trackDb *findCompositeTdb(struct trackDb *track, char *table)
 /*      find the tdb for the table, if it is custom or composite or ordinary  */
 {
 struct trackDb *tdb = track;
 
 if (isCustomTrack(table))
@@ -842,31 +843,31 @@
 
 /* Print out label and drop-down list. */
 hPrintf("<B>table: </B>");
 hPrintf("<SELECT NAME=\"%s\" id='%s'>\n", varName, varName);
 jsOnEventById("change",varName,onChangeTable());
 for (name = nameList; name != NULL; name = name->next)
     {
     struct trackDb *tdb = NULL;
     if (track != NULL)
         tdb = findCompositeTdb(track, name->name);
     hPrintf("<OPTION VALUE=\"%s\"", name->name);
     if (sameString(selTable, name->name))
         hPrintf(" SELECTED");
     if (tdb != NULL)
         if ((curTrack == NULL) || differentWord(tdb->shortLabel, curTrack->shortLabel))
-            hPrintf(">%s (%s)\n", tdb->shortLabel, name->name);
+            hPrintf(">%s (%s)\n", htmlEncode(tdb->shortLabel), name->name); // label in dropdown text, escape (XSS)
         else
             hPrintf(">%s\n", name->name);
     else
         hPrintf(">%s\n", name->name);
     }
 hPrintf("</SELECT>\n");
 return selTable;
 }
 
 
 
 void importPage(struct sqlConnection *conn)
 /* Put up initial import page. */
 {
 struct grp *selGroup;