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/hgTables/mainPage.c src/hg/hgTables/mainPage.c index a41bcc9..77573c1 100644 --- src/hg/hgTables/mainPage.c +++ src/hg/hgTables/mainPage.c @@ -1,1003 +1,1015 @@ /* mainPage - stuff to put up the first table browser page. */ /* Copyright (C) 2014 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 "htmshell.h" #include "cheapcgi.h" #include "cart.h" #include "cartTrackDb.h" #include "textOut.h" #include "jksql.h" #include "hdb.h" #include "web.h" #include "jsHelper.h" #include "hui.h" #include "hgColors.h" #include "trackDb.h" #include "grp.h" #include "hgTables.h" #include "joiner.h" #include "trackDb.h" #include "hubConnect.h" #include "trackHub.h" #include "hgConfig.h" static struct dyString *onChangeStart() /* Start up a javascript onChange command */ { struct dyString *dy = jsOnChangeStart(); jsDropDownCarryOver(dy, hgtaTrack); jsDropDownCarryOver(dy, hgtaGroup); jsTrackedVarCarryOver(dy, hgtaRegionType, "regionType"); jsTextCarryOver(dy, hgtaRange); jsDropDownCarryOver(dy, hgtaOutputType); jsTextCarryOver(dy, hgtaOutFileName); return dy; } static char *onChangeClade() /* Return javascript executed when they change clade. */ { struct dyString *dy = onChangeStart(); jsDropDownCarryOver(dy, "clade"); jsDropDownCarryOver(dy, hgtaTable); dyStringAppend(dy, " document.hiddenForm.org.value=0;"); dyStringAppend(dy, " document.hiddenForm.db.value=0;"); dyStringAppend(dy, " document.hiddenForm.position.value='';"); return jsOnChangeEnd(&dy); } static char *onChangeOrg() /* Return javascript executed when they change organism. */ { struct dyString *dy = onChangeStart(); jsDropDownCarryOver(dy, "clade"); jsDropDownCarryOver(dy, "org"); jsDropDownCarryOver(dy, hgtaTable); dyStringAppend(dy, " document.hiddenForm.db.value=0;"); dyStringAppend(dy, " document.hiddenForm.position.value='';"); return jsOnChangeEnd(&dy); } static char *onChangeDb() /* Return javascript executed when they change database. */ { struct dyString *dy = onChangeStart(); jsDropDownCarryOver(dy, "clade"); jsDropDownCarryOver(dy, "db"); jsDropDownCarryOver(dy, hgtaTable); dyStringAppend(dy, " document.hiddenForm.position.value='';"); return jsOnChangeEnd(&dy); } static char *onChangeGroupOrTrack() /* Return javascript executed when they change group. */ { struct dyString *dy = onChangeStart(); jsDropDownCarryOver(dy, "clade"); jsDropDownCarryOver(dy, "db"); jsDropDownCarryOver(dy, "org"); dyStringPrintf(dy, " document.hiddenForm.%s.value=0;", hgtaTable); return jsOnChangeEnd(&dy); } static char *onChangeTable() /* Return javascript executed when they change group. */ { struct dyString *dy = onChangeStart(); jsDropDownCarryOver(dy, "clade"); jsDropDownCarryOver(dy, "db"); jsDropDownCarryOver(dy, "org"); jsDropDownCarryOver(dy, hgtaTable); return jsOnChangeEnd(&dy); } void makeRegionButtonExtraHtml(char *val, char *selVal, char *extraHtml) /* Make region radio button including a little Javascript to save selection state * and optional extra html attributes. */ { jsMakeTrackingRadioButtonExtraHtml(hgtaRegionType, "regionType", val, selVal, extraHtml); } void makeRegionButton(char *val, char *selVal) /* Make region radio button including a little Javascript * to save selection state. */ { makeRegionButtonExtraHtml(val, selVal, NULL); } -struct grp *showGroupField(char *groupVar, char *groupScript, +struct grp *showGroupField(char *groupVar, char *event, char *groupScript, struct sqlConnection *conn, boolean allTablesOk) /* Show group control. Returns selected group. */ { struct grp *group, *groupList = fullGroupList; struct grp *selGroup = findSelectedGroup(groupList, groupVar); hPrintf("group:\n"); -hPrintf("\n", groupVar, groupVar); +jsOnEventById(event,groupVar,groupScript); for (group = groupList; group != NULL; group = group->next) { if (allTablesOk || differentString(group->name, "allTables")) hPrintf(" ", track->shortLabel); } } if (selTrackIsDisabled) selTrack = firstEnabled; hPrintf("\n"); } hPrintf("\n"); return selTrack; } char *unsplitTableName(char *table) /* Convert chr*_name to name */ { if (startsWith("chr", table)) { char *s = strrchr(table, '_'); if (s != NULL) { table = s + 1; } } return table; } struct slName *tablesForDb(char *db) /* Find tables associated with database. */ { boolean isGenomeDb = sameString(db, database); struct sqlConnection *conn = hAllocConn(db); struct slName *raw, *rawList = sqlListTables(conn); struct slName *cooked, *cookedList = NULL; struct hash *uniqHash = newHash(0); hFreeConn(&conn); for (raw = rawList; raw != NULL; raw = raw->next) { if (cartTrackDbIsAccessDenied(db, raw->name)) continue; if (isGenomeDb) { /* Deal with tables split across chromosomes. */ char *root = unsplitTableName(raw->name); if (cartTrackDbIsAccessDenied(db, root)) continue; if (!hashLookup(uniqHash, root)) { hashAdd(uniqHash, root, NULL); cooked = slNameNew(root); slAddHead(&cookedList, cooked); } } else { char dbTable[256]; safef(dbTable, sizeof(dbTable), "%s.%s", db, raw->name); cooked = slNameNew(dbTable); slAddHead(&cookedList, cooked); } } hashFree(&uniqHash); slFreeList(&rawList); slSort(&cookedList, slNameCmp); return cookedList; } char *showTableField(struct trackDb *track, char *varName, boolean useJoiner) /* Show table control and label. */ { struct slName *name, *nameList = NULL; char *selTable; if (track == NULL) nameList = tablesForDb(findSelDb()); else nameList = cartTrackDbTablesForTrack(database, track, useJoiner); /* Get currently selected table. If it isn't in our list * then revert to first in list. */ selTable = cartUsualString(cart, varName, nameList->name); if (!slNameInListUseCase(nameList, selTable)) selTable = nameList->name; /* Print out label and drop-down list. */ hPrintf("table: "); -hPrintf("\n", varName, varName); +jsOnEventById("change", varName, onChangeTable()); struct trackDb *selTdb = NULL; for (name = nameList; name != NULL; name = name->next) { struct trackDb *tdb = NULL; if (track != NULL) tdb = findTdbForTable(database,track,name->name, ctLookupName); hPrintf("