a53b9958fa734f73aeffb9ddfe2fbad1ca65f90c galt Mon Jan 30 16:18:41 2017 -0800 Check-in of CSP2 Content-Security-Policy work. All C-language CGIs should now support CSP2 in browser to stop major forms of XSS javascript injection. Javascript on pages is gathered together, and then emitted in a single script block at the end with a nonce that tells the browser, this is js that we generated instead of being injected by a hacker. Both inline script from script blocks and inline js event handlers had to be pulled out and separated. You will not see js sprinkled through-out the page now. Older browsers that support CSP1 or that do not understand CSP at all will still work, just without protection. External js libraries loaded at runtime need to be added to the CSP policy header in src/lib/htmshell.c. diff --git src/hg/hgPublicSessions/hgPublicSessions.c src/hg/hgPublicSessions/hgPublicSessions.c index 5d2c0da..f512133 100644 --- src/hg/hgPublicSessions/hgPublicSessions.c +++ src/hg/hgPublicSessions/hgPublicSessions.c @@ -1,299 +1,307 @@ /* hgPublicSessions - A gallery for hgTracks sessions. */ /* Copyright (C) 2016 The Regents of the University of California * See README in this or parent directory for licensing information. */ #include "common.h" #include "linefile.h" #include "hash.h" #include "options.h" #include "jksql.h" #include "htmshell.h" #include "web.h" #include "cheapcgi.h" #include "cart.h" #include "hui.h" #include "ra.h" #include "dystring.h" #include "hPrint.h" #include "hgConfig.h" #include "sessionThumbnail.h" #include "jsHelper.h" #include "verbose.h" struct galleryEntry /* Holds data for a single session in the gallery*/ { struct galleryEntry *next; char *userName; char *realName; char *sessionName; char *settings; char *db; char *firstUse; char *imgPath; char *imgUri; struct dyString *sessionUrl; unsigned long useCount; }; /* Global Variables */ struct cart *cart; /* CGI and other variables */ struct hash *oldVars = NULL; struct galleryEntry *galLoad(char **row) /* Load a session entry from a row. A row consists of: * 0. gbMembers.realName * 1. namedSessionDb.userName * 2. gbMembers.idx * 3. namedSessionDb.sessionName * 4. namedSessionDb.useCount * 5. namedSessionDb.settings * 6. namedSessionDb.contents * 7. namedSessionDb.firstUse */ { char *dbIdx, *dbEnd; struct galleryEntry *ret; AllocVar(ret); ret->realName = cloneString(row[0]); ret->userName = cloneString(row[1]); cgiDecodeFull(ret->userName, ret->userName, strlen(ret->userName)); ret->sessionName = cloneString(row[3]); cgiDecodeFull(ret->sessionName, ret->sessionName, strlen(ret->sessionName)); ret->sessionUrl = dyStringCreate("hgS_doOtherUser=submit&hgS_otherUserName=%s&hgS_otherUserSessionName=%s", row[1], row[3]); ret->imgPath = sessionThumbnailFilePath(row[2], row[3], row[7]); if (fileExists(ret->imgPath)) ret->imgUri = sessionThumbnailFileUri(row[2], row[3], row[7]); else ret->imgUri = NULL; ret->useCount = sqlUnsignedLong(row[4]); ret->settings = cloneString(row[5]); if (startsWith("db=", row[6])) dbIdx = row[6] + 3; else dbIdx = strstr(row[6], "&db=") + 4; if (dbIdx != NULL) { dbEnd = strchr(dbIdx, '&'); if (dbEnd != NULL) ret->db = cloneStringZ(dbIdx, dbEnd-dbIdx); else ret->db = cloneString(dbIdx); } else ret->db = cloneString("n/a"); ret->firstUse = cloneString(row[7]); char *spacePt = strchr(ret->firstUse, ' '); if (spacePt != NULL) *spacePt = '\0'; return ret; } void deleteGallery (struct galleryEntry **pGal) /* Free all memory associated with a gallery entry */ { struct galleryEntry *gal; if ((gal = *pGal) != NULL) { freeMem(gal->realName); freeMem(gal->userName); freeMem(gal->sessionName); freeMem(gal->settings); freeMem(gal->db); freeMem(gal->firstUse); freeMem(gal->imgPath); freeMem(gal->imgUri); dyStringFree(&(gal->sessionUrl)); freez(pGal); } } struct galleryEntry *galleryFetch() /* Return an slList of gallery entries fetched from hgcentral */ { struct sqlConnection *conn = hConnectCentral(); struct sqlResult *sr = NULL; struct galleryEntry *gal, *galList = NULL; char otherConstraints[80] = "", query[2048], **row; sqlSafef (query, sizeof(query), "select m.realName, s.userName, m.idx, s.sessionName, s.useCount, s.settings, s.contents, s.firstUse from " "%s s left join gbMembers m on m.userName = s.userName where shared = 2%s" , namedSessionTable, otherConstraints); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { gal = galLoad(row); slAddHead (&galList, gal); } sqlFreeResult(&sr); hDisconnectCentral(&conn); return galList; } void galleryDisplay(struct galleryEntry *galList) /* Print a table containing the gallery data from galList */ { struct galleryEntry *thisSession = galList; /* Hide the orderable columns and disable ordering on the visible columns * https://datatables.net/reference/option/columnDefs for more info. * Then set up the ordering drop-down menu */ -printf ("\n"); printf ("
\n"); -printf ("Sort by:
\n"); +jsOnEventById("change", "sortMethod", "changeSort();"); printf ("Screenshot | \n" "Session Properties | \n" "Creation Date | \n" "Use Count | \n" "|
---|---|---|---|---|
",
dyStringContents(thisSession->sessionUrl));
printf (" | \n", thisSession->imgUri);
}
else
{
printf ("\t\t\n"); printf ("\t\tClick Here to view | \n",
dyStringContents(thisSession->sessionUrl));
}
struct hash *settingsHash = raFromString(thisSession->settings);
settingString = (char*) hashFindVal(settingsHash, "description");
if (settingString == NULL)
settingString = "";
else
{
settingString = replaceChars(settingString, "\\\\", "\\__ESC__");
settingString = replaceChars(settingString, "\\r", "\r");
settingString = replaceChars(settingString, "\\n", "\n");
settingString = replaceChars(settingString, "\\__ESC__", "\\");
}
printf ("\t\tDescription: %s \n", settingString); printf ("\t\tAuthor: %s \n", thisSession->userName); printf ("\t\tSession Name: %s \n", thisSession->sessionName); printf ("\t\tGenome Assembly: %s \n", thisSession->db); printf ("\t\tCreation Date: %s \n", thisSession->firstUse); printf ("\t\tViews: %ld\n", thisSession->useCount); printf ("\t\t | \n");
struct tm creationDate;
strptime(thisSession->firstUse, "%Y-%m-%d", &creationDate);
/* Hidden columns */
printf ("\t\t%ld | \n", mktime(&creationDate)); printf ("\t\t%ld | \n", thisSession->useCount); printf ("\t
Sessions allow users to save snapshots of the Genome Browser " "and its current configuration, including displayed tracks, position, " "and custom track data. The Public Sessions tool allows users to easily " "share those sessions that they deem interesting with the rest of the " "world's researchers. You can add your own sessions to this list by " "checking the appropriate box on the " "Session Management page.
\n" "See the " "Sessions User's Guide " "for more information.\n
", cartSidUrlString(cart)); showGalleryTab(); cartWebEnd(); } /* Null terminated list of CGI Variables we don't want to save * permanently. */ char *excludeVars[] = {"Submit", "submit", NULL,}; int main(int argc, char *argv[]) /* Process command line. */ { cgiSpoof(&argc, argv); cartEmptyShell(doMiddle, hUserCookie(), excludeVars, oldVars); return 0; }