ee89e6768015d512b5ca8db8a62e8a129dfd5c7f braney Sun Aug 23 15:56:57 2026 -0700 hgSession, cartReset: send the content policy header on their own pages Both CGIs write their own http header block, so neither reaches addHttpHeaders in cart.c, the hook that carries the policy header. hgSession lets each output path write its own Content-Type, and cartReset gets its header from htmShellWithHead. Add the call ahead of each html Content-Type: the two main page functions in hgSession.c, three more in backup.c, and the one in cartReset. The json paths and the tar download are left alone, since they print no html. With the hg.conf option off this changes nothing. With it on, both pages now carry the header, and its nonce matches the one in the meta tag and on the inline script tags. diff --git src/hg/hgSession/backup.c src/hg/hgSession/backup.c index 8583af67bf5..f484092aaa7 100644 --- src/hg/hgSession/backup.c +++ src/hg/hgSession/backup.c @@ -44,30 +44,31 @@ if(strstr(format, "needLargeMem:") || strstr(format, "carefulAlloc:")) htmlVaWarn("Region selected is too large for calculation. Please specify a smaller region or try limiting to fewer data points.", args); else { // call previous handler popWarnHandler(); vaWarn(format, args); } if(isErrAbortInProgress()) noWarnAbort(); } static void vaHtmlOpen(char *format, va_list args) /* Start up a page that will be in html format. */ { +cspWriteResponseHeader(); puts("Content-Type:text/html\n"); cartVaWebStart(cart, database, format, args); pushWarnHandler(errAbortHandler); } void htmlOpen(char *format, ...) /* Start up a page that will be in html format. */ { va_list args; va_start(args, format); vaHtmlOpen(format, args); va_end(args); } void htmlClose() @@ -165,30 +166,31 @@ htmlOpen("Background Status"); errAbort("No complete html found"); htmlClose(); return; } int start; for (start=end; start >= 0 && ! (startsWith("", lines[start]) || startsWith("", lines[start])) ; --start) /* do nothing */ ; if (start < 0) { htmlOpen("Background Status"); errAbort("No html start tag found"); htmlClose(); return; } +cspWriteResponseHeader(); puts("Content-Type: text/html\n"); int line; boolean autoRefreshFound = FALSE; boolean successfullyUploaded = FALSE; for (line=start; line <= end; line++) { puts(lines[line]); if (startsWith("setTimeout(function(){location = location;}", lines[line])) autoRefreshFound = TRUE; if (startsWith("Output has been successfully uploaded", lines[line])) successfullyUploaded = TRUE; } // if it looks like the background is no longer running, // include the .err stdout output for more informative problem message char urlErr[512]; @@ -705,30 +707,31 @@ } printf("
\n"); printf("
\n"); } void showDownloadSessionCtData(struct hashEl *downloadList) /* Show download page for the given session */ { char query[512]; char **row = NULL; struct sqlResult *sr = NULL; +cspWriteResponseHeader(); puts("Content-Type:text/html\n"); cartWebStart(cart, NULL, "Backup Custom Tracks"); jsInit(); struct sqlConnection *conn = hConnectCentral(); printf("
\n", hgSessionName()); cartSaveSession(cart); sqlSafef(query, sizeof(query), "SELECT firstUse, contents from %s " "WHERE id=%lu", "sessionDb", cartSessionRawId(cart));