2eb14fc0378432977d83366a3211c67f8913018d max Mon Sep 21 06:21:51 2026 -0700 hgc and hgTrackUi: open off-site links in a new tab, with rel="noopener noreferrer" offsiteLinksToNewTab() in utils.js runs over the rendered page alongside addHgsidToLinks() and gives every http(s) link whose host is not ours a target=_blank it does not already have, plus rel="noopener noreferrer". Without noopener the page that opens keeps a handle on the tab it came from and can navigate it; without noreferrer the Referer header carries our own URL, which has the session id in it. The href on a track description page is written by whoever wrote the track or the hub, so neither is theoretical. A mailto: or an ftp: link is left alone, and so is every link that stays on this server. jsAddHgsidToLinks() now emits both calls and is renamed jsFixUpPageLinks(). hgTracks.js runs the same pass over the track description popup: the replace it does before that already puts a target on every link in there, so what this adds is the rel on the ones that leave. refs #38380 diff --git src/hg/hgTrackUi/hgTrackUi.c src/hg/hgTrackUi/hgTrackUi.c index d7edeb8f5e5..bbb9878110f 100644 --- src/hg/hgTrackUi/hgTrackUi.c +++ src/hg/hgTrackUi/hgTrackUi.c @@ -4772,31 +4772,31 @@ "<span style='background-color: #c3d4f4; " "padding-left: 10px; padding-right: 10px;" "margin-right: 10px; margin-left: -8px;'>" "%s</span> %s", htmlEncode(tdb->parent->shortLabel), htmlEncode(tdb->shortLabel)); } else dyStringPrintf(title, "%s", htmlEncode(tdb->shortLabel)); char *titleEnd = (tdbIsSuper(tdb) ? "Tracks" : tdbIsDownloadsOnly(tdb) ? DOWNLOADS_ONLY_TITLE : "Track Settings"); htmlNoEscape(); // allow HTML tags to format title blue bar (using short label) cartWebStart(cart, database, "%s %s", title->string, titleEnd); htmlDoEscape(); trackUi(tdb, tdbList, ct, FALSE); printf("<BR>\n"); - jsAddHgsidToLinks(); + jsFixUpPageLinks(); jsonPrintGlobals(); webEnd(); } } char *excludeVars[] = { "submit", "Submit", "g", "fileUrl", "track", "sourceDb", NULL, "ajax", NULL,}; int main(int argc, char *argv[]) /* Process command line. */ { long enteredMainTime = clock1000(); /* 0, 0, == use default 10 second for warning, 20 second for immediate exit */ issueBotWarning = earlyBotCheck(enteredMainTime, "hgTrackUi", delayFraction, 0, 0, "html"); cgiSpoof(&argc, argv); cartEmptyShellNoContent(doMiddle, hUserCookie(), excludeVars, NULL);