54413ab8e05496303b70ee4349b4e5ada1802147
max
  Wed Feb 4 03:40:06 2026 -0800
adding XSS security fix to hub error printf, refs #36916

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index 20a4459b34d..83d95764bfc 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -8753,31 +8753,31 @@
 
 unsigned getParaLoadTimeout()
 // get the parallel load timeout in seconds (defaults to 90)
 {
 char *paraLoadTimeoutStr = cartOptionalString(cart, "parallelFetch.timeout");
 if (paraLoadTimeoutStr == NULL)
     paraLoadTimeoutStr = cfgOptionDefault("parallelFetch.timeout", "90");  // wait up to default 90 seconds.
 
 unsigned paraLoadTimeout = sqlUnsigned(paraLoadTimeoutStr);
 
 return paraLoadTimeout;
 }
 
 static char *hubPublicEmailFromHubName(char *hubName)
 {
-/* return public hub email given url or NULL if such a column doesn't exist (mirrors don't have this column) */
+/* return public hub email given hubName or NULL if such a column doesn't exist (mirrors don't have this column) */
 /* result must be freed */
 char *hubIdStr = strchr(hubName, '_'); // could not find a function for this in hubConnect.c
 if (!hubIdStr)
     return NULL;
 unsigned hubId = sqlUnsigned(hubIdStr+1);
 
 struct hubConnectStatus *hubStatus = hubFromIdNoAbort(hubId);                                                           
 if (hubStatus == NULL)
     return NULL;
 
 char *url = hubStatus->hubUrl;
 if (!url)
     return NULL;
 
 struct sqlConnection *conn = hConnectCentral();
@@ -9935,34 +9935,34 @@
                 {
                 // we want tracks in the visible list to also be visible
                 // in the normal group list, so use a separate hash for the
                 // visible tracks grouping
                 groupTrackListAddSuper(cart, group, hashNew(8), hashNew(8));
                 }
             else
                 groupTrackListAddSuper(cart, group, superHash, trackHash);
 
 	    /* Display track controls */
             if (group->errMessage)
                 {
                 hPrintf("<tr><td colspan=8><b>Track hub error</b> ");
                 printInfoIcon("Use the hub debugging tool under <i>My Data > Track Hubs > Hub Development</i>. You need to switch off <i>File caching</i> there to see your changes without delay. Error <i>Response is missing required header</i> usually means the hub is not reachable.<br><br>Contact us or the hub provider if you cannot resolve the issue.");
                 hPrintf(": ");
-                hPrintf("<i>%s</i>", group->errMessage);
+                hPrintf("<i>%s</i>", stripHtml(cloneString(group->errMessage)));
                 char *email = hubPublicEmailFromHubName(hubName);
                 if (isNotEmpty(email))
-                    hPrintf("<br>You can contact the hub author at %s", email);
+                    hPrintf("<br>You can contact the hub author at %s", stripHtml(email));
                 hPrintf("</td></tr>\n");
                 }
 
 	    for (tr = group->trackList; tr != NULL; tr = tr->next)
 		{
 		struct track *track = tr->track;
 		if (tdbIsSuperTrackChild(track->tdb))
 		    /* don't display supertrack members */
 		    continue;
                 // only top level tracks contribute to the total count
                 trackCount++;
 		myControlGridStartCell(cg, isOpen, group->name,
                                        shouldBreakAll(track->shortLabel));
 
                 printTrackLink(track);