Open Bug 1272404 Opened 9 years ago Updated 3 years ago

Firefox 46.0.1 does not send JSON POST requests correctly webseal

Categories

(Core :: DOM: Core & HTML, defect)

46 Branch
defect

Tracking

()

UNCONFIRMED

People

(Reporter: mikebaker1967, Unassigned, NeedInfo)

Details

(Whiteboard: btpp-followup-2016-05-27)

User Agent: Mozilla/5.0 (Windows NT 5.1; rv:43.0) Gecko/20100101 Firefox/43.0 SeaMonkey/2.40 Build ID: 20160120202951 Steps to reproduce: Tried logon to online banking at bbt,com Actual results: Got the error: "We are sorry, but we were unable to complete your last request. Please click the Back button and try again." https://online.bbt.com/auth/prompt.tb?TAM_OP=error&USERNAME=unauthenticated&ERROR_CODE=0x38cf081d&ERROR_TEXT=DPWWA2077E%20%20%20Could%20not%20authenticate%20user.%20%20An%20EAI%20server%20returned%20invalid%20authentication%20data.&URL=%2Fauth%2Fpwd.tb Expected results: Logged in as normal. BBT claims to be waiting for a response from Firefox support. Advises me to use IE or Chrome. According to IBM: http://www.ibm.com/support/knowledgecenter/SSXJVR_2.0.0/com.ibm.sso.doc_2.0.0/trouble_web/concept/con_json_post_firefox_issue.html May 3, 2016 Firefox does not send JSON POST requests correctly When using the Firefox browser, JSON POST requests specified in the WebSEAL configuration file are not parsed. Your policies might produce incorrect or unexpected results. In the WebSEAL configuration file, you can capture JSON data for a custom attribute by using the [azn-decision-info] stanza. In that stanza, if you have an entry for post-data that specifies JSON POST data, it will not be parsed. Use an alternate browser when you have custom attributes configured that specify JSON POST requests. For example, use Chrome or Internet Explorer. Parent topic: Common problems with WebSEAL servers
The error happens with Firefox 46.0.1
It's surely a dupe of bug 1269055 which is already fixed in 47+. Could you download Beta and test, please. https://www.mozilla.org/en-US/firefox/beta/all/
Component: Untriaged → Networking: HTTP
Flags: needinfo?(mikebaker1967)
Product: Firefox → Core
updated to 47.0b4 and I get the same error.
Flags: needinfo?(mikebaker1967)
Installed Chrome V 49.0.2623.112 m and It worked. I was able to login.
(In reply to MikeBaker from comment #3) > updated to 47.0b4 and I get the same error. 47.0b4 contains patch for bug 1269055, hence not a dup. This sounds to me as a XHR issue, which is a DOM code.
Component: Networking: HTTP → DOM
Mike, can you open the network panel and capture the json POST? It would be nice to see the request headers. It would also be nice to know if we make an OPTIONS request before the POST.
Flags: needinfo?(mikebaker1967)
Whiteboard: btpp-followup-2016-05-27
// This object maps the BB&T glbPageData format to the appropriate SiteCatalyst variables // This should only be populated once and is therefore global var scDataMap = { //The format goes scDataMap[glbPageData.variable]=s.variable; pageType : "pageType", pageId : "pageName", pageName : "pageName", event : "events", events : "events", channel : "channel", //cdata server : "server", //cdata hier : "hier1", //NOT SET! hier (heir1) product : "products", products : "products", loggedIn : "prop5", //cdata olbUser : "prop7,eVar30", secQuestion : "prop8", olbNum : "prop9,eVar9", //cdata secMsg : "prop12,eVar31", statSusp : "prop14", workId : "prop15,eVar15", editError : "prop17", //cdata resumeIndicator : "prop18,eVar16", generalPath : "prop21", path : "prop21", //cdata error : "prop17", //cdata caseId : "prop41,eVar28", productId : "prop47", eventMapping : "prop49,eVar49", //NOT SET! eventMapping (prop49, eVar49) portlet : "prop53", //cdata portletCount : "prop54", //cdata existingClient : "eVar10", clientType : "eVar11", //cdata selectedAccounts : "eVar12", promoCode : "eVar14", editUserRole : "eVar72", sessionId : "eVar74", appStatus : "prop11", searchTerm : "prop1,eVar1", //cdata searchResults : "prop3", //cdata phone : "eVar13", //cdata actionName : "prop24,eVar19", //CONTENTION! prop8 in cdata cta : "prop24,eVar19", //cdata social : "prop43", //cdata supportSession : "prop56,eVar56", secFeature : "prop57,eVar57" //cdata }; /* * This function builds and sends an s.t() based on the input data object * Note that dynamic page loads must be indicated with a dynmaicPageLoad == true */ function trackPageObject(scDataObject,dynamicPageLoad){ if (s) { var localDataObject = {}; // if declared AND defined if (typeof scDataObject !== 'undefined') { localDataObject = clone(scDataObject); // If an object was not supplied attempt to populate. } else { if (typeof glbPageData !== 'undefined') { localDataObject = clone(glbPageData); } else if(typeof oaoPageData !== 'undefined') { localDataObject = clone(oaoPageData); } else { return; } } setSiteCatalystDataObject(localDataObject); // Process any IntLink (internal link) tracking information retrieveIntLink(); // Capture any PEGA campaign codes s.eVar33 = captureCampaignCodes(); // If this is a dynamic page load run doPlugins again. if (dynamicPageLoad) {s.doPlugins=s_doPlugins;} //s.t(); clearEvents = true; } } /* * This function builds and sends an s.tl() (based on the input data object) when the user clicks a link. * Option linkEvent is the link click event which is required for links with hrefs to properly record * Option linkName is included otherwise this will default to prop21 or href if the linkEvent is supplied * Option linkType is included for exit or download links which should be specified as "e" or "d" respectively */ function trackLinkObject(scDataObject,linkEvent,linkName,linkType){ if (s) { var localDataObject = {}; // if declared AND defined if (typeof scDataObject !== 'undefined') { localDataObject = clone(scDataObject); // If an object was not supplied attempt to populate. } else { if (typeof glbClickData !== 'undefined') { localDataObject = clone(glbClickData); } else { return; } } // Populate the SiteCatalyst variables using the scDataMap setSiteCatalystDataObject(localDataObject,true); // Set linkEvent to true if it doesn't exist if (typeof linkEvent === 'undefined') linkEvent = true; // Set linkType if not already set if (typeof linkType === 'undefined') linkType = 'o'; // Make certain trackExternalLinks is on if this is an exit link if (linkType == 'e') s.trackExternalLinks=true; // Set linkName if not already set if (typeof linkName === 'undefined') { if ((s.prop21) && (s.prop21 !== s.pageName)) { // Use custom path if available linkName = s.prop21; } else if (linkEvent != true) { // For standard links, use default SC method linkName = undefined; } else { // This occurs if a javascript link has no name nor custom path linkName = "(unnamed_link)"; } } s.tl(linkEvent,linkType,linkName); clearEvents = true; } } /* * This function offers an alternative for Dynamic Page tracking */ function trackDynamicPageObject(scDataObject){ trackPageObject(scDataObject,true); } /* * This function offers an alternative for Exit Link tracking */ function trackExitLinkObject(scDataObject,linkEvent,linkName){ trackLinkObject(scDataObject,linkEvent,linkName,'e'); } /* * This function offers an alternative for Download tracking */ function trackDownloadObject(scDataObject,linkEvent,linkName){ trackLinkObject(scDataObject,linkEvent,linkName,'d'); } /* * This function cleans up N/A values and converts 0 and false values to strings */ function trackingVariablePrep(obj,property) { var typeCheck = typeof obj[property]; if(typeCheck === "undefined"){ delete obj[property]; } else { // Clear out N/A values if(typeCheck !== "number" && typeCheck !== "boolean"){ if(obj[property].indexOf('N/A')>=0) { obj[property] = ""; } } else if (obj[property] === 0) { // Preserve 0 values obj[property] = "0"; } else if (obj[property] === false) { // Preserve false values obj[property] = "false"; } } } /* * This function translates an scDataObject into s.variables based upon scDataMap and preprocessing */ function setSiteCatalystDataObject(scDataObject,linkTracking) { //assume this is page tracking unless noted otherwise through linkTracking if (typeof scDataObject === 'undefined') { return } // First set s.linkTrackVars if linkTracking is set if (linkTracking) {s.linkTrackVars = "";} // Second check to see ensure olbNum isn't set to N/A or blank trackingVariablePrep(scDataObject,"olbNum"); // Third check to see ensure CaseID isn't set to N/A or blank trackingVariablePrep(scDataObject,"caseId"); // Forth check to see if this is a 404 page load. // Note that s.prop21 defaults to equal s.pageName but can be overwritten later if (!linkTracking) { if (scDataObject.pageType=='errorPage') { s.pageType = scDataObject.pageType; s.prop21 = location.href; } else { delete s.pageType; // Set s.pageName based on pageName, pageId, path, or URL if (scDataObject.pageName) { s.pageName = scDataObject.pageName; } else if (scDataObject.pageId) { s.pageName = scDataObject.pageId; } else if (scDataObject.path) { s.pageName = scDataObject.path; } s.prop21 = "D=pageName"; } } else { if (scDataObject.pageName) { s.pageName = scDataObject.pageName; } else if (scDataObject.pageId) { s.pageName = scDataObject.pageId; } } // Now we are done with pageType, pageName, pageId. Remove to avoid multiple references. delete scDataObject.pageType; delete scDataObject.pageName; delete scDataObject.pageId; // Fifth check if any events need appending // Check if event or events are being used and combine if both. if (scDataObject.events) { scDataObject.event = (scDataObject.event ? scDataObject.event + "," + scDataObject.events : scDataObject.events); } if (typeof scDataObject.event !== 'undefined') { // If event2 is to be set but the OAO has already been visited, then removed event2 scDataObject.event = oaoCheck(scDataObject.event,scDataObject.channel); // Reset events if clearEvents is set to true (meaning the page already sent tracking at least once) if (typeof clearEvents === 'undefined' || clearEvents == false) { s.events = s.apl(s.events,scDataObject.event,',',1); } else { s.events = scDataObject.event; } if(s.events){ // Check linkTracking to see if additional variables must be set if (linkTracking) { s.linkTrackVars="events"; s.linkTrackEvents=s.events.replace(/(=[0-9]+)/g,""); } // Check if event merits serialization using caseId if (scDataObject.caseId) { // Build an array to place each seperate event into. var eventsArray = s.events.split(","); for (var i=0; i<eventsArray.length; ++i) { eventsArray[i] = eventsArray[i]+':'+scDataObject.caseId.replace(/-/g, ''); } s.events = eventsArray.join(); } } } // Now we are done with event(s). Remove to avoid multiple references delete scDataObject.events; delete scDataObject.event; // Sixth set all remaining variables using the SiteCatalyst Data Map for (var property in scDataObject) { trackingVariablePrep(scDataObject,property); //Some Data Mappings included multiple variables, which must all be set individually if (scDataMap[property]) { var propArray = scDataMap[property].split(","); for (var i=0; i < propArray.length; ++i){ s[propArray[i]] = scDataObject[property]; } // This iteration includes an additional step if part of link tracking if (linkTracking && scDataObject[property]) { s.linkTrackVars = s.apl(s.linkTrackVars,scDataMap[property],',',1); } delete scDataObject[property]; } } //TEST THE CROSS-DEVICE VISITOR ID if (s.prop9 && s_account.indexOf("bbtdevall")>-1){ s.visitorID = s.prop9; s.eVar75 = s.prop9; } } function captureCampaignCodes() { var campidmaj = s.c_r('CampIDMaj'), campidmin = s.c_r('CampIDMin'), referralsource = s.c_r('ReferralSource'), scVariable = s.channel; if (campidmaj && campidmin && referralsource) { scVariable += ":" + campidmaj + campidmin + ":" + referralsource; } else { scVariable += ":no_tracking_code"; } if (s.prop41) { scVariable += ":with_caseid:" + s.prop41; } else { scVariable += ":without_caseid"; } return scVariable; } function retrieveIntLink() { // link tracking code below if (document.cookie.indexOf("intlinklabel") != -1) { var intlinklabel = s.c_r('intlinklabel'), intlinkid = s.c_r('intlinkid'); var intlinktype = (!intlinkid) ? "b" : intlinkid.substring(5,6); if (intlinklabel.indexOf("src=")==0) { intlinklabel = intlinklabel.substring(intlinklabel.indexOf("src=")+5); } else { intlinklabel = intlinklabel.toLowerCase().replace(/ /g, "_"); } s.prop20 = intlinktype + ":" + intlinklabel; s.eVar20 = "D=c20"; // now delete the cookies document.cookie = "intlinkurl=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;"; document.cookie = "intlinklabel=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;"; document.cookie = "intlinkid=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;"; } } /* * Required to clone and disassociate an object */ function clone(obj) { var fooArray = new Array(); var attrArray = new Array(); // Find all functions and convert to string for (var attr in obj) { if (typeof(obj[attr]) == 'function') { fooArray.push(obj[attr].toString()); attrArray.push(attr); } } // Stringify the object (ignoring functions) var serialized = JSON.stringify(obj); //$.toJSON(obj); // // Deserialize object var copy = JSON.parse(serialized); //$.evalJSON(serialized); // // Add functions for (var i = 0 ; i < fooArray.length ; i++) { copy[attrArray[i]] = eval('(' + fooArray[i] + ')'); } return copy; } var JSON = JSON || {}; // implement JSON.stringify serialization JSON.stringify = JSON.stringify || function (obj) { var t = typeof (obj); if (t != "object" || obj === null) { // simple data type if (t == "string") obj = '"'+obj+'"'; return String(obj); } else { // recurse array or object var n, v, json = [], arr = (obj && obj.constructor == Array); for (n in obj) { v = obj[n]; t = typeof(v); if (t == "string") v = '"'+v+'"'; else if (t == "object" && v !== null) v = JSON.stringify(v); json.push((arr ? "" : '"' + n + '":') + String(v)); } return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}"); } }; // implement JSON.parse de-serialization JSON.parse = JSON.parse || function (str) { if (str === "") str = '""'; eval("var p=" + str + ";"); return p; }; /* if (s) { if (s_account.indexOf("myfi") != -1) { return ''; } else if (typeof glbPageData !== 'undefined') { trackPageObject(glbPageData); } else if (typeof oaoPageData !== 'undefined') { trackPageObject(oaoPageData); } else { //s.t(); clearEvents = true; } } */ // Cookie Serialization Version 1.0 // Checks the s_oao cookie to see if the Current OAO has already been used with event2. If it hasn't then the events are passed back. // Currently this only supports use with event2 on the various OAOs. function oaoCheck(sc_events,oao_channel) { // Ensure that event2 is in sc_events before proceeding if (typeof sc_events === 'undefined') { return; } if ((sc_events.indexOf("event2") == -1)||(typeof oao_channel === 'undefined')){ return sc_events; } // Break up the channel to determine which OAO we're on and begin the new_s_oao variable with that. var new_s_oao=oao_channel.slice(oao_channel.indexOf(":")+1); // Get the existing s_oao cookie value var s_oao=s.c_r("s_oao"); // Check to see if the old s_oao cookie had any oao's listed. // Then check if those include the current oao. If so then remove event2. If not then append the old s_oao value to the new s_oao value. if (s_oao){ if (s_oao.indexOf(new_s_oao)!=-1){ //Split out the list, find event2, remove it, then join the array and send. var eventsArray = sc_events.split(","); for(var i = 0 ; i < eventsArray.length ; i++) { if(eventsArray[i] == "event2") { eventsArray.splice(i, 1); return eventsArray.join(","); } } } else { s_oao+=","+new_s_oao; } } else { s_oao=new_s_oao; } // set the expiration date to 30 minutes from the current time and the build the cookie based on new s_oao var exdate=new Date(); exdate.setTime(exdate.getTime()+1800000); document.cookie="s_oao="+s_oao+"; expires="+exdate.toUTCString()+";domain=.bbt.com; path=/"; return sc_events; }
Updated to v48 beta 9 and the JSON problem has not been corrected. I have to use Chrome to login to BBT. I don't like to use Chrome because I think it tracks your every move and then Google uses that to profit from users and feed the what they want them to see.
Component: DOM → DOM: Core & HTML
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.