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/hgVai/hgVai.c src/hg/hgVai/hgVai.c index 97b1d58..de80f63 100644 --- src/hg/hgVai/hgVai.c +++ src/hg/hgVai/hgVai.c @@ -146,32 +146,32 @@ dyStringAppend(dy, " document.hiddenForm." hgvaRange ".value='';"); return jsOnChangeEnd(&dy); } INLINE void printOption(char *val, char *selectedVal, char *label) /* For rolling our own select without having to build conditional arrays/lists. */ { printf("", selected); struct slName *option; for (option = optionList; option != NULL; option = option->next) { selected = ""; if (selHash && hashLookup(selHash, option->name)) selected = " selected"; printf("%s", selected, option->name); } printf("\n"); char shadowVar[1024]; safef(shadowVar, sizeof(shadowVar), "%s%s", cgiMultListShadowPrefix(), cartVar); cgiMakeHiddenVar(shadowVar, "1"); -//printf("\n", cartVar); +// +char javascript[1024]; +safef(javascript, sizeof javascript, + "$(document).ready(function(){ ddcl.setup($('#%s')[0]); });\n", cartVar); +jsInline(javascript); } void printFilterOptions(struct trackDb *tdb) /* Print a collapsible filter section for tdb, with controls depending on tdb->type. */ { char sectionName[512], cartVar[512]; safef(sectionName, sizeof(sectionName), "%s_filter", tdb->track); if (sameString(tdb->type, "factorSource")) { puts(""); startSmallCollapsibleSection(sectionName, "filter items", FALSE); struct slName *factorOptions = NULL, *cellTypeOptions = NULL, *treatmentOptions = NULL; factorSourceListInputProperties(tdb, &factorOptions, &cellTypeOptions, &treatmentOptions); printMultiselect(tdb->track, "factor", "name", factorOptions); printMultiselect(tdb->track, "cell type", "cellType", cellTypeOptions); printMultiselect(tdb->track, "treatment", "treatment", treatmentOptions); puts("
"); puts("minimum peak score [0-1000]: "); safef(cartVar, sizeof(cartVar), "hgva_filter_%s_score", tdb->track); char *defaultScore = cartUsualString(cart, cartVar, "0"); printf("
", cartVar, defaultScore); // The dimensions of ui-dropdownchecklist multiselects are not correct when // the item is hidden. So, when this filter section is made visible, reinit them. - printf("\n", sectionName); + "});\n" + , sectionName); + jsInline(javascript); puts("
"); endCollapsibleSection(); } if (startsWith("bed 5", tdb->type)) //#*** TODO: detect bed# properly { puts(""); startSmallCollapsibleSection(sectionName, "filter items", FALSE); //#*** Also watch out for noScoreFilter or whatever it's called puts("minimum peak score [0-1000]: "); safef(cartVar, sizeof(cartVar), "hgva_filter_%s_score", tdb->track); char *defaultScore = cartUsualString(cart, cartVar, "0"); printf("
", cartVar, defaultScore); puts("
"); endCollapsibleSection(); @@ -446,47 +452,47 @@ void selectVariants() /* Offer selection of user's variant custom tracks, example variants, pasted input etc. */ { #define PGSNP_OR_VCF "pgSnp or " \ "VCF" printf("
Select Variants
\n"); /* Check for variant custom tracks. If there are none, tell the user that they should add one. */ struct slRef *varTrackList = NULL, *varGroupList = NULL; tdbFilterGroupTrack(fullTrackList, fullGroupList, isVariantCustomTrack, NULL, &varGroupList, &varTrackList); if (varTrackList == NULL) { printf("Your session doesn't have any custom tracks or hub tracks in " PGSNP_OR_VCF " format.\n"); - hOnClickButton("return hgva.goToAddCustomTrack();", + hOnClickButton("selVar_AddPgpVcfCt", "return hgva.goToAddCustomTrack();", "add pgSnp or VCF custom track"); if (hubConnectTableExists()) { nbSpaces(2); - hOnClickButton("document.trackHubForm.submit(); return false;", "add track hub"); + hOnClickButton("selVar_AddTrkHub", "document.trackHubForm.submit(); return false;", "add track hub"); } puts("
"); } else if (slCount(varTrackList) > 1) { printf("If you have more than one custom track or hub track in " PGSNP_OR_VCF " format, please select the one you wish to annotate:
\n"); } printf("variants: "); -printf("\n"); +jsOnEventById("change", "hgva_variantTrack", "hgva.changeVariantSource();"); char *selected = cartUsualString(cart, "hgva_variantTrack", ""); struct slRef *ref; for (ref = varTrackList; ref != NULL; ref = ref->next) { struct trackDb *tdb = ref->val; printOption(tdb->track, selected, tdb->longLabel); } printOption(hgvaSampleVariants, selected, hgvaSampleVariantsLabel); boolean hasSnps = (hFindLatestSnpTable(database, NULL) != NULL); if (hasSnps) printOption(hgvaUseVariantIds, selected, hgvaVariantIdsLabel); printf("
\n"); if (hasSnps) { @@ -531,32 +537,32 @@ printf("to determine the effect of " "each variant on genes, for example intronic, missense, splice site, intergenic etc."); if (!gotGP) printf(" Since this assembly has no gene prediction tracks, " "the VAI can't provide functional annotations. " "Please select a different genome.
"); printf("
\n"); if (! gotGP) return NULL; char *firstTrack = ((struct trackDb *)(trackRefList->val))->track; char *selected = cartUsualString(cart, "hgva_geneTrack", firstTrack); //#*** should show more info about each track... button to pop up track desc? if (gotGP) { - printf("\n"); + jsOnEventById("change", "hgva_geneTrack", "hgva.changeGeneSource();"); struct slRef *ref; for (ref = trackRefList; ref != NULL; ref = ref->next) { struct trackDb *tdb = ref->val; if (tdb->subtracks == NULL) printOption(tdb->track, selected, tdb->longLabel); } puts("
"); } return selected; } //#*** We really need a dbNsfp.[ch]: enum PolyPhen2Subset { noSubset, HDIV, HVAR }; @@ -1201,33 +1207,33 @@ { struct trackDb *tdb = elTrackRefList->val; printf(" %s
\n", tdb->longLabel); cgiMakeHiddenVar("hgva_require_consEl_track", tdb->track); puts(""); } else { puts(""); char *selected = cartUsualString(cart, "hgva_require_consEl_track", ""); struct slRef *ref; for (ref = elTrackRefList; ref != NULL; ref = ref->next) { printf(""); struct trackDb *tdb = ref->val; - cgiMakeOnClickRadioButton("hgva_require_consEl_track", tdb->track, + cgiMakeOnEventRadioButtonWithClass("hgva_require_consEl_track", tdb->track, sameString(tdb->track, selected), - "onclick=\"setCheckboxList('hgva_require_consEl', true);\""); + NULL, "click", "setCheckboxList('hgva_require_consEl', true);"); printf("%s\n", tdb->longLabel); } puts(""); } endCollapsibleSection(); } void selectFilters() /* Options to restrict output to variants with specific properties */ { puts("
"); printf("
Define Filters
\n"); puts(""); selectFiltersFunc(); selectFiltersKnownVar(); @@ -1260,64 +1266,66 @@ sameWord(textOutCompressGzip, compressType)); printf(" gzip compressed (ignored if output file is blank)"); puts("
"); } void submitAndDisclaimer() { puts("
"); puts("This tool is for research use only. While this tool is open to the " "public, users seeking information about a personal medical or genetic " "condition are urged to consult with a qualified physician for " "diagnosis and for answers to personal questions."); puts("

"); printf("
\n"); printf("
\n"); -cgiMakeOnClickButton("hgva.submitQueryIfDisclaimerAgreed();", "Get results"); +cgiMakeOnClickButton("subDisclmAgrd","hgva.submitQueryIfDisclaimerAgreed();", "Get results"); puts("

"); } /* * When user clicks submit, we need to roll a JSON querySpec from form selections, * and show data from a submission to hgAnnoGrator. redirect from this CGI? * or have javascript submit directly? * * primary: variants, from custom track * * if there are genes, those w/annoGratorGpVar * * if there are {dbSNP, dbNsfp, regulatory, cons} selections, grator for each of those * * vep output config * * If we get bold & offer 1000Genomes VCF, will def. need handling of split chroms. * Are we really going to offer genome-wide in hgVai? * Up-front limit on #rows of input ? * * Eventually, we might want a FormatVep that produces structs that are passed * forward to multiple output writers... I would want to send it lots of gratorData * like a formatter, but it would produce rows like an annoGrator. * Maybe annoGrators should accept a bunch of input rows like formatters? * or would this grator wrap all the input grators inside? */ void doMainPage() /* Print out initial HTML of control page. */ { jsInit(); webIncludeResourceFile("jquery-ui.css"); webIncludeResourceFile("ui.dropdownchecklist.css"); boolean alreadyAgreed = cartUsualBoolean(cart, "hgva_agreedToDisclaimer", FALSE); -printf("\n", alreadyAgreed ? "true" : "false"); + , alreadyAgreed ? "true" : "false"); +jsInline(javascript); addSomeCss(); printAssemblySection(); puts("
"); // Make wrapper table for collapsible sections: selectVariants(); char *geneTrack = selectGenes(); if (geneTrack != NULL) { selectRegulatory(); selectAnnotations(geneTrack); selectFilters(); selectOutput(); submitAndDisclaimer(); }