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/hgLiftOver/hgLiftOver.c src/hg/hgLiftOver/hgLiftOver.c
index 185a4765863..10d4ed4a3b1 100644
--- src/hg/hgLiftOver/hgLiftOver.c
+++ src/hg/hgLiftOver/hgLiftOver.c
@@ -598,31 +598,36 @@
}
if (errCt)
{
/* some records not converted */
cgiParagraph("");
printf("Conversion failed on %d record", errCt);
printf("%s. ", errCt > 1 ? "s" : "");
printf("
Display failure file \n",
unmappedTn.forCgi);
printf("
Explain failure messages\n", HGLFT_ERRORHELP_VAR);
puts("
Failed input regions:\n"); struct lineFile *errFile = lineFileOpen(unmappedTn.forCgi, TRUE); puts("
\n");
while (lineFileNext(errFile, &line, &lineSize))
- puts(line);
+ {
+ // these are the user's own failed input regions, escape before echoing (XSS)
+ char *encoded = htmlEncode(line);
+ puts(encoded);
+ freeMem(encoded);
+ }
lineFileClose(&errFile);
puts("\n");
}
if ((multiple) && (lft == positions))
{
puts("\n");
puts("Note: "multiple" option is not supported for position format.");
puts("\n");
}
webParamsUsed(minMatch, multiple, minSizeQ, minChainT, minBlocks, fudgeThick);
carefulClose(&unmapped);
}
}
errCatchEnd(errCatch);