f759bf663debc22e6015c6c38c22f922bfbdf45b braney Fri Aug 21 10:01:02 2026 -0700 lib, cgilib: sanitize description HTML where it comes in, refs #38126 A track hub's track description, a custom track's documentation, and an assembly hub's genome description are all written by somebody else and were stored and printed as they arrived. Run each through htmlSanitize() at the point it is read, so that everything downstream sees text we are willing to print. Sanitizing on the way in is the only practical place: printTrackHtml() alone has more than a hundred callers, and hgTrackUi, hui.c, hgGene, hgGtexTrackSettings and hgTables all print tdb->html directly. The five places are trackHubAddOneDescription(), customTrack.c where it used to call jsStripJavascript(), the htmlUrl fetch in customFactory.c, hgPositionsHelpHtmlCart() and hAssemblyDescription(). In the last two, only the branch that fetches over the network is touched. The branch that reads a local file is left as it is, because those are our own description.html files. trackHubAddOneDescription() keeps its old shape. The fetch moves into a helper so that trackHubDescriptionRemovals() can hand hubCheck the list of things the filter takes out. diff --git src/hg/lib/customTrack.c src/hg/lib/customTrack.c index 74df0b83f57..1bcbe9523a2 100644 --- src/hg/lib/customTrack.c +++ src/hg/lib/customTrack.c @@ -2,30 +2,31 @@ * See also customFactory, which is where the parsing is done. */ /* Copyright (C) 2014 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 "obscure.h" #include "memalloc.h" #include "portable.h" #include "errAbort.h" #include "errCatch.h" #include "linefile.h" #include "sqlList.h" #include "jksql.h" +#include "htmlSanitize.h" #include "customTrack.h" #include "myVariants.h" #include "ctgPos.h" #include "psl.h" #include "gff.h" #include "genePred.h" #include "net.h" #include "hdb.h" #include "hui.h" #include "cheapcgi.h" #include "wiggle.h" #include "hgConfig.h" #include "customFactory.h" #include "trashDir.h" #include "jsHelper.h" @@ -865,31 +866,31 @@ { /* unreadable file */ struct dyString *ds = dyStringNew(0); dyStringPrintf(ds, "Can't read doc file: %s", docFileName); err = dyStringCannibalize(&ds); customText = NULL; } } else html = cartUsualString(cart, CT_CUSTOM_DOC_TEXT_VAR, ""); html = cloneString(html); /* do not let original cart var get eaten up */ html = customDocParse(html); /* this will chew up the input string */ if(html != NULL) { char *tmp = html; - html = jsStripJavascript(html); + html = htmlSanitize(html); freeMem(tmp); } else html = cloneString(""); /* the doc file could not be read, see above */ if ((strlen(html) > 50*1024) || startsWith("track ", html) || startsWith("browser ", html)) { err = cloneString( "Optional track documentation appears to be either too large (greater than 50k) or it starts with a track or browser line. " "This is usually an indication that the data has been accidentally put into the documentation field. " "Only html documentation is intended for this field. " "Please correct and re-submit."); html = NULL; /* we do not want to save this bad value */ customText = NULL; /* trigger a return to the edit page */ }