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/apiUtils.c src/hg/hubApi/apiUtils.c index a288be641e7..7a482b0c1bd 100644 --- src/hg/hubApi/apiUtils.c +++ src/hg/hubApi/apiUtils.c @@ -8,30 +8,31 @@ /* when measureTiming is used */ static long processingStart = 0; void startProcessTiming() /* for measureTiming, beginning processing */ { processingStart = clock1000(); } void apiFinishOutput(int errorCode, char *errorString, struct jsonWrite *jw) /* finish json output, potential output an error code other than 200 */ { /* this is the first time any output to stdout has taken place for * json output, therefore, start with the appropriate header. */ +puts("X-Content-Type-Options: nosniff"); puts("Content-Type:application/json"); /* potentially with an error code return in the header */ if (errorCode) { char errString[2048]; safef(errString, sizeof(errString), "Status: %d %s",errorCode,errorString); puts(errString); if (err429 == errorCode) puts("Retry-After: 30"); } else if (reachedMaxItems) { char errString[2048]; safef(errString, sizeof(errString), "Status: %d %s",err206,err206Msg); puts(errString); @@ -830,30 +831,31 @@ 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); dyStringPrintf(textOutput, "%s\n", outString); safef(outString, sizeof(outString), "# downloadTimeStamp: %lld", (long long) timeNow); dyStringPrintf(textOutput, "%s\n", outString); } } dyStringPrintf(textOutput, "%s\n", lineOut); } void textFinishOutput() /* all done with text output, print it all out */ { +puts("X-Content-Type-Options: nosniff"); puts("Content-Type:text/plain\n"); printf("%s", dyStringCannibalize(&textOutput)); } static char *thisHostName() /* Return this machine's own hostname via gethostname(). Unlike hHttpHost(), * which reflects the client-supplied HTTP_HOST/Host: header, this can't be * spoofed by the request and doesn't change depending on which round-robin * name (e.g. genome.ucsc.edu) the client used to reach this box -- using * hHttpHost() here made onGenomeRRMachine() misclassify RR machines reached * via the genome.ucsc.edu name, sending them into an infinite self-relay * loop. */ { static char host[256]; static boolean init = FALSE;