87300988042f9b370f257fddf5a3ae0d21662851 galt Sat Feb 4 00:12:53 2017 -0800 Fixes for early warning during ajax callback; fixes for early warning in js. Changed to not only parse to but strip out the CSP header and js-with-nonce leaving cleaner html -- should create fewer "surprises" for existing screen-scraping code. diff --git src/hg/js/utils.js src/hg/js/utils.js index 2cfefd4..e31b9d6 100644 --- src/hg/js/utils.js +++ src/hg/js/utils.js @@ -662,46 +662,48 @@ $(button).attr('title', 'Expand this '+titleDesc); contents.hide(); } else { $(button).attr('title', 'Collapse this '+titleDesc); contents.show().trigger('show'); } $(hidden).val(newVal); if (doAjax) { setCartVar(hiddenPrefix+"_"+prefix+"_close", newVal); } retval = false; } return retval; } -function getNonce() +function getNonce(debug) { // Gets nonce value from page meta header var content = $("meta[http-equiv='Content-Security-Policy']").attr("content"); if (!content) return ""; // parse nonce like 'nonce-JDPiW8odQkiav4UCeXsa34ElFm7o' var sectionBegin = "'nonce-"; var sectionEnd = "'"; var ix = content.indexOf(sectionBegin); if (ix < 0) return ""; content = content.substring(ix+sectionBegin.length); ix = content.indexOf(sectionEnd); if (ix < 0) return ""; content = content.substring(0,ix); +if (debug) + alert('page nonce='+content); return content; } function warnBoxJsSetup() { // Sets up warnBox if not already established. This is duplicated from htmshell.c var html = ""; html += "
','
',cleanHtml,bounds.start,bounds.stop); + // OLD WAY var warnMsg = bindings.insideOut('','
',cleanHtml,bounds.start,bounds.stop); + var warnMsg = cleanHtml.slice(bounds.start+begToken.length,bounds.stop-endToken.length); if (warnMsg.length > 0) { warn(warnMsg); if (whatWeDid) whatWeDid.warnMsg = warnMsg; } cleanHtml = cleanHtml.slice(0,bounds.start) + cleanHtml.slice(bounds.stop); } return cleanHtml; } function stripJsFiles(returnedHtml, debug, whatWeDid) { // strips javascript files from html returned by ajax var cleanHtml = returnedHtml; var shlurpPattern=/"; var lastIx = 0; - var ix = content.indexOf(sectionBegin, lastIx); + while (1) { + var ix = html.indexOf(sectionBegin, lastIx); if (ix < 0) - return results; - ix += sectionBegin.length; - var ex = content.indexOf(sectionEnd, ix); + break; + var ix2 = ix + sectionBegin.length; + var ex = html.indexOf(sectionEnd, ix2); if (ex < 0) - return results; - var jsNonce = content.substring(ix,ex); + break; + content += html.substring(lastIx,ix); + var jsNonce = html.substring(ix2,ex); if (debug) - alert("jsNonce:'"+jsNonce); + alert("jsNonce:"+jsNonce); results.push(jsNonce); - lastIx = ex; - ex += sectionEnd.length; - return results; + lastIx = ex + sectionEnd.length; + } + // grab the last piece. + content += html.substring(lastIx); + + //return results; + if (whatWeDid) + whatWeDid.js = results; + + return content; + } function charsAreHex(s) // are all the chars found hex? { var hexChars = "01234566789abcdefABCDEF"; var d = false; var i = 0; if (s) { d = true; while (i < s.length) { if (hexChars.indexOf(s.charAt(i++)) < 0) d = false; } } @@ -1598,30 +1609,69 @@ if (!matched) d = d + s.charAt(i++); } } return d; } function jsDecode(s) // For JS string values decode "\xHH" { return nonAlphaNumericHexDecodeText(s, "\\x", ""); } +function stripCSPAndNonceJs(content, debug, whatWeDid) +// Strip CSP Header and script blocks with the ajax nonce. +{ + + var pageNonce = getNonce(debug); + + var csp = {}; + content = stripCspHeader(content, debug, csp); + + var ajaxNonce = parseNonce(csp.csp, debug); + + var jsBlocks = {}; + content = stripJsNonce(content, ajaxNonce, debug, jsBlocks); + + if (whatWeDid) { + whatWeDid.pageNonce = pageNonce; + whatWeDid.ajaxNonce = ajaxNonce; // Not in use yet. + whatWeDid.js = jsBlocks.js; + } + + return stripHgErrors(content, whatWeDid); // Certain early errors are not called via warnBox + +} + +function appendNonceJsToPage(jsNonce) +// Append ajax js blocks with nonce. +// Create jsNonce by calling stripCSPAndNonceJs. +// Call this after ajax html content has been added to the page/DOM. +{ + var i; + for (i=0; i