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/hgSession/hgSession.c src/hg/hgSession/hgSession.c
index 5837b6a1040..0f7eaa4de1c 100644
--- src/hg/hgSession/hgSession.c
+++ src/hg/hgSession/hgSession.c
@@ -1528,32 +1528,32 @@
}
char *doOtherUser(char *actionVar)
/* Load settings from another user's named session.
* Return a message confirming what we did. */
{
struct sqlConnection *conn = hConnectCentral();
struct dyString *dyMessage = dyStringNew(1024);
char *otherUser = trimSpaces(cartString(cart, hgsOtherUserName));
char *sessionName = trimSpaces(cartString(cart, hgsOtherUserSessionName));
char *encOtherUser = cgiEncodeFull(otherUser);
char *encSessionName = cgiEncodeFull(sessionName);
dyStringPrintf(dyMessage,
"Loaded settings from user %s's session %s. %s %s",
- otherUser, htmlEncode(sessionName),
- getSessionLink(otherUser, encSessionName),
+ htmlEncode(otherUser), htmlEncode(sessionName),
+ getSessionLink(encOtherUser, encSessionName),
getSessionEmailLink(encOtherUser, encSessionName));
cartLoadUserSession(conn, otherUser, sessionName, cart, NULL, actionVar);
cartCopyLocalHubs(cart);
hubConnectLoadHubs(cart);
cartHideDefaultTracks(cart);
cartCheckForCustomTracks(cart, dyMessage);
hDisconnectCentral(&conn);
return dyStringCannibalize(&dyMessage);
}
void doSaveLocal()
/* Output current settings to be saved as a file on the user's machine.
* Return a message confirming what we did. */
{
char *fileName = textOutSanitizeHttpFileName(cartString(cart, hgsSaveLocalFileName));
@@ -1580,31 +1580,31 @@
struct dyString *dyMessage = dyStringNew(1024);
struct lineFile *lf = NULL;
webPushErrHandlersCartDb(cart, cartUsualString(cart, "db", NULL));
if (fromUrl)
{
char *url = trimSpaces(cartString(cart, hgsLoadUrlName));
if (isEmpty(url))
errAbort("Please go back and enter the URL (http://..., ftp://...) "
"of a file that contains "
"previously saved browser settings, and then click "
"\"submit\" again.");
if (!startsWith("http://",url) && !startsWith("https://",url) && !startsWith("ftp://",url))
errAbort("Unsupported protocol for loading a file via URL. Please use http, https, or ftp");
lf = netLineFileOpen(url);
dyStringPrintf(dyMessage, "Loaded settings from URL %s . %s %s",
- url, getUrlLink(url), getUrlEmailLink(url));
+ htmlEncode(url), getUrlLink(url), getUrlEmailLink(url));
}
else
{
char *filePlainContents = cartOptionalString(cart, hgsLoadLocalFileName);
char *fileBinaryCoords = cartOptionalString(cart,
hgsLoadLocalFileName "__binary");
char *fileName = cartOptionalString(cart,
hgsLoadLocalFileName "__filename");
if (isNotEmpty(filePlainContents))
{
char *settings = trimSpaces(filePlainContents);
dyStringAppend(dyMessage, "Loaded settings from local file ");
if (isNotEmpty(fileName))
dyStringPrintf(dyMessage, "%s ", fileName);
dyStringPrintf(dyMessage, "(%lu bytes).",