ae1b9adc9d85808683118f771703aeb8970306bf
braney
  Sat Aug 22 10:19:03 2026 -0700
hubApi: add X-Content-Type-Options: nosniff to responses, refs #38163

Set the nosniff header ahead of the Content-Type on every hubApi output
path (JSON, text, and html), so responses declare their type explicitly.

diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c
index 979e8fa8725..5171cc1d578 100644
--- src/hg/hubApi/hubApi.c
+++ src/hg/hubApi/hubApi.c
@@ -1149,30 +1149,31 @@
 hPrintf("</pre>\n");
 }
 
 static void sendJsonHogMessage(char *hogHost)
 {
 apiErrAbort(err429, err429Msg, "Your host, %s, has been sending too many requests lately and is "
        "unfairly loading our site, impacting performance for other users. "
        "Please contact genome-www@soe.ucsc.edu to ask that your site "
        "be reenabled.  Also, please consider downloading sequence and/or "
        "annotations in bulk -- see http://genome.ucsc.edu/downloads.html.",
        hogHost);
 }
 
 static void sendHogMessage(char *hogHost)
 {
+puts("X-Content-Type-Options: nosniff");
 puts("Content-Type:text/html");
 hPrintf("Status: %d %s\n", err429, err429Msg);
 puts("Retry-After: 30");
 puts("\n");
 
 hPrintf("<!DOCTYPE HTML>\n");
 hPrintf("<html lang='en'>\n");
 hPrintf("<head>\n");
 hPrintf("<meta charset=\"utf-8\">\n");
 hPrintf("<title>Status %d %s</title></head>\n", err429, err429Msg);
 
 hPrintf("<body><h1>Status %d %s</h1><p>\n", err429, err429Msg);
 hPrintf("Your host, %s, has been sending too many requests lately and is "
        "unfairly loading our site, impacting performance for other users. "
        "Please contact genome-www@soe.ucsc.edu to ask that your site "
@@ -1658,30 +1659,31 @@
 	if (n == -1)	/* can use -1 to indicate as much as allowed */
 	    maxItemsOutput = maxItemLimit;
 	else if (n > maxItemLimit)	/* safety check */
 	    apiErrAbort(err400, err400Msg, "requested maxItemsOutput '%s' greater than maximum limit allowed: %d", maxOut, maxItemLimit);
 	else if (n < 1)
 	    apiErrAbort(err400, err400Msg, "requested maxItemsOutput '%s' can not be less than one", maxOut, maxItemLimit);
 	else
 	    maxItemsOutput = n;
 	}
     }
 }	/*	static void setGlobalCgiVars()	*/
 
 static void redirectToHelp()
 /* redirect to the help page */
 {
+puts("X-Content-Type-Options: nosniff");
 puts("Content-Type:text/html");
 hPrintf("Status: %d %s\n", err301, err301Msg);
 hPrintf("Location: /goldenPath/help/api.html\n");
 puts("\n");
 
 hPrintf("<!DOCTYPE HTML>\n");
 hPrintf("<html lang='en'>\n");
 hPrintf("<head>\n");
 hPrintf("<meta http-equiv='Refresh' content='0; url=/goldenPath/help/api.html' />\n");
 hPrintf("</head>\n");
 }
 
 /* Null terminated list of CGI Variables we don't want to save
  * permanently. */
 static char *excludeVars[] = {"Submit", "submit", "sourceSelected", "selectRadio", "ucscGenome", "publicHubs", "clade", NULL,};