Closed michaellewis259 closed 4 years ago
Hi Michael!
Unfortunately I cannot reproduce this behaviour. Could you please launch the dev tools (F12) within the extension window and see if it outputs some stacktrace or something similar at the console-tab?
I'm showing a few errors:
debug from the first JS error: `/**
// export SAMLTrace namespace to make ao. Request definitions available var EXPORTED_SYMBOLS = ["SAMLTraceIO"];
// Put functionality in out own namespace if ("undefined" == typeof(SAMLTraceIO)) { var SAMLTraceIO = {}; };
SAMLTraceIO = function() { };
SAMLTraceIO.prototype = { /**
Main feature: Exports and optionally filters traced requests. **/ 'exportRequests': function(reqs, cookieProfile) { // Perform request filtering based on user input from dialog: var ef = new SAMLTraceIO.ExportFilter(cookieProfile); var filteredreqs = ef.perform(reqs);
// Package results var result = { requests: filteredreqs, timestamp: new Date().toISOString() }; return result; },
'serialize': function(exportResult) { let indentSpaces = 2; return JSON.stringify(exportResult, null, indentSpaces); },
'getOutputFile': function(exportResult) {
let timeStamp = exportResult && exportResult.timestamp ? exportResult.timestamp : "no-timestamp";
return SAML-tracer-export-${timeStamp}.json
;
},
/**
Imports requests and restores them in the TraceWindow. **/ 'importRequests': function(selectedFile, tracer, onSuccess, onError) { const parseRequests = rawResult => { try { let exportedSession = JSON.parse(rawResult); let successfullyRestored = this.restoreFromImport(exportedSession.requests, tracer, onError); if (successfullyRestored) { onSuccess(); } } catch (error) { console.log("An error occured while trying to parse and import requests: " + error); if (error instanceof SyntaxError) { onError("The selected file doesn't seem to contain importable traces!"); } else if (error instanceof TypeError) { onError("The selected file seems to be invalid or corrupted!"); } else { onError("Error while importing: " + error); } } };
let reader = new FileReader(); reader.onload = e => { parseRequests(e.target.result); } reader.readAsText(selectedFile); },
'restoreFromImport' : function(importedRequests, tracer, onError) { if (!importedRequests || importedRequests.length === 0) { onError("There aren't any requests to import..."); return false; }
// Since the relase of v1.0.0 every request's got a "requestId". If it ain't present, it's a legacy import.
let isLegacyImport = !importedRequests[0].hasOwnProperty("requestId");
console.log(The imported requests are in ${isLegacyImport ? "legacy" : "current"}-style.
);
const getHeaders = importedHeaders => { if (isLegacyImport) { return importedHeaders.map(h => { return { name: h[0], value: h[1] } }); } else { return importedHeaders; } };
const getRequestId = importedRequest => { return isLegacyImport ? importedRequest.id : importedRequest.requestId; };
const createRestoreableModel = importedRequest => { let pseudoRequest = { req: { method: importedRequest.method, url: importedRequest.url, requestId: getRequestId(importedRequest), requestBody: { post: importedRequest.post } }, requestId: getRequestId(importedRequest), url: importedRequest.url, headers: getHeaders(importedRequest.requestHeaders), saml: importedRequest.saml, getResponse: () => { let pseudoResponse = { requestId: getRequestId(importedRequest), url: importedRequest.url, statusCode: importedRequest.responseStatus, statusLine: importedRequest.responseStatusText, responseHeaders: getHeaders(importedRequest.responseHeaders) }; return pseudoResponse; } }; return pseudoRequest; };
let restoreableRequests = importedRequests.map(ir => createRestoreableModel(ir)); restoreableRequests.forEach(rr => { tracer.saveNewRequest(rr); tracer.addRequestItem(rr, rr.getResponse); tracer.attachResponseToRequest(rr.getResponse()); });
return true; } };
/**
SAMLTraceIO.ExportFilter.prototype = { 'loadPreferences' : function(cookieProfile) { this.exportFilters = [];
switch (cookieProfile) {
case '1' : // No cookiefiltering or filtering whatsoever
break;
case '2' : // Apply hash filters
this.exportFilters.push(
SAMLTraceIO_filters.hashValueFilter('post', '*'), // hash *all* the post elements
SAMLTraceIO_filters.overwriteKeyValue('postData'), // overwrite the postData-variable
SAMLTraceIO_filters.hashCookieValueFilter('requestHeaders', 'Cookie'), // hash cookie values in request
SAMLTraceIO_filters.hashCookieValueFilter('responseHeaders', 'Set-Cookie') // ..as well as in response
);
break;
case '3' : // Apply obfuscate/overwrite filters
this.exportFilters.push(
SAMLTraceIO_filters.obfuscateValueFilter('post', '*'), // obfuscate *all* the post elements
SAMLTraceIO_filters.overwriteKeyValue('postData'), // overwrite the postData-variable
SAMLTraceIO_filters.obfuscateCookieValueFilter('requestHeaders', 'Cookie'), // obfuscate cookie values in request
SAMLTraceIO_filters.obfuscateCookieValueFilter('responseHeaders', 'Set-Cookie') // ..as well as in response
);
break;
}
},
'perform' : function(reqs) { let the_filters = this.exportFilters; // move from instance to local scope
const createFromJSON = function(obj) {
let stringified = JSON.stringify(obj);
return JSON.parse(stringified);
};
const enrichWithResponse = (req, res) => {
let responseCopy = createFromJSON(res);
req.responseStatus = responseCopy.statusCode;
req.responseStatusText = responseCopy.statusLine;
req.responseHeaders = responseCopy.responseHeaders;
};
let reqscopy = reqs.map(req => {
let newRequest = createFromJSON(req);
enrichWithResponse(newRequest, req.getResponse());
the_filters.forEach(filter => filter(newRequest));
return newRequest;
});
return reqscopy;
} }; `
and second: `/**
// export SAMLTrace namespace to make ao. Request definitions available var EXPORTED_SYMBOLS = ["SAMLTraceIO"];
// Put functionality in out own namespace if ("undefined" == typeof(SAMLTraceIO)) { var SAMLTraceIO = {}; };
SAMLTraceIO = function() { };
SAMLTraceIO.prototype = { /**
Main feature: Exports and optionally filters traced requests. **/ 'exportRequests': function(reqs, cookieProfile) { // Perform request filtering based on user input from dialog: var ef = new SAMLTraceIO.ExportFilter(cookieProfile); var filteredreqs = ef.perform(reqs);
// Package results var result = { requests: filteredreqs, timestamp: new Date().toISOString() }; return result; },
'serialize': function(exportResult) { let indentSpaces = 2; return JSON.stringify(exportResult, null, indentSpaces); },
'getOutputFile': function(exportResult) {
let timeStamp = exportResult && exportResult.timestamp ? exportResult.timestamp : "no-timestamp";
return SAML-tracer-export-${timeStamp}.json
;
},
/**
Imports requests and restores them in the TraceWindow. **/ 'importRequests': function(selectedFile, tracer, onSuccess, onError) { const parseRequests = rawResult => { try { let exportedSession = JSON.parse(rawResult); let successfullyRestored = this.restoreFromImport(exportedSession.requests, tracer, onError); if (successfullyRestored) { onSuccess(); } } catch (error) { console.log("An error occured while trying to parse and import requests: " + error); if (error instanceof SyntaxError) { onError("The selected file doesn't seem to contain importable traces!"); } else if (error instanceof TypeError) { onError("The selected file seems to be invalid or corrupted!"); } else { onError("Error while importing: " + error); } } };
let reader = new FileReader(); reader.onload = e => { parseRequests(e.target.result); } reader.readAsText(selectedFile); },
'restoreFromImport' : function(importedRequests, tracer, onError) { if (!importedRequests || importedRequests.length === 0) { onError("There aren't any requests to import..."); return false; }
// Since the relase of v1.0.0 every request's got a "requestId". If it ain't present, it's a legacy import.
let isLegacyImport = !importedRequests[0].hasOwnProperty("requestId");
console.log(The imported requests are in ${isLegacyImport ? "legacy" : "current"}-style.
);
const getHeaders = importedHeaders => { if (isLegacyImport) { return importedHeaders.map(h => { return { name: h[0], value: h[1] } }); } else { return importedHeaders; } };
const getRequestId = importedRequest => { return isLegacyImport ? importedRequest.id : importedRequest.requestId; };
const createRestoreableModel = importedRequest => { let pseudoRequest = { req: { method: importedRequest.method, url: importedRequest.url, requestId: getRequestId(importedRequest), requestBody: { post: importedRequest.post } }, requestId: getRequestId(importedRequest), url: importedRequest.url, headers: getHeaders(importedRequest.requestHeaders), saml: importedRequest.saml, getResponse: () => { let pseudoResponse = { requestId: getRequestId(importedRequest), url: importedRequest.url, statusCode: importedRequest.responseStatus, statusLine: importedRequest.responseStatusText, responseHeaders: getHeaders(importedRequest.responseHeaders) }; return pseudoResponse; } }; return pseudoRequest; };
let restoreableRequests = importedRequests.map(ir => createRestoreableModel(ir)); restoreableRequests.forEach(rr => { tracer.saveNewRequest(rr); tracer.addRequestItem(rr, rr.getResponse); tracer.attachResponseToRequest(rr.getResponse()); });
return true; } };
/**
SAMLTraceIO.ExportFilter.prototype = { 'loadPreferences' : function(cookieProfile) { this.exportFilters = [];
switch (cookieProfile) {
case '1' : // No cookiefiltering or filtering whatsoever
break;
case '2' : // Apply hash filters
this.exportFilters.push(
SAMLTraceIO_filters.hashValueFilter('post', '*'), // hash *all* the post elements
SAMLTraceIO_filters.overwriteKeyValue('postData'), // overwrite the postData-variable
SAMLTraceIO_filters.hashCookieValueFilter('requestHeaders', 'Cookie'), // hash cookie values in request
SAMLTraceIO_filters.hashCookieValueFilter('responseHeaders', 'Set-Cookie') // ..as well as in response
);
break;
case '3' : // Apply obfuscate/overwrite filters
this.exportFilters.push(
SAMLTraceIO_filters.obfuscateValueFilter('post', '*'), // obfuscate *all* the post elements
SAMLTraceIO_filters.overwriteKeyValue('postData'), // overwrite the postData-variable
SAMLTraceIO_filters.obfuscateCookieValueFilter('requestHeaders', 'Cookie'), // obfuscate cookie values in request
SAMLTraceIO_filters.obfuscateCookieValueFilter('responseHeaders', 'Set-Cookie') // ..as well as in response
);
break;
}
},
'perform' : function(reqs) { let the_filters = this.exportFilters; // move from instance to local scope
const createFromJSON = function(obj) {
let stringified = JSON.stringify(obj);
return JSON.parse(stringified);
};
const enrichWithResponse = (req, res) => {
let responseCopy = createFromJSON(res);
req.responseStatus = responseCopy.statusCode;
req.responseStatusText = responseCopy.statusLine;
req.responseHeaders = responseCopy.responseHeaders;
};
let reqscopy = reqs.map(req => {
let newRequest = createFromJSON(req);
enrichWithResponse(newRequest, req.getResponse());
the_filters.forEach(filter => filter(newRequest));
return newRequest;
});
return reqscopy;
} };`
Does this occur for each and every trace you try to export? Or does it only happen, when there's a certain request contained in the trace?
Could you please try make a small trace. E.g. just trace the request to this issue. Is it exportable?
I could very well imagine that there's a single request in your trace which causes the error. We probably need to narrow down the source of the problem 😉
I receive this error on ANY export attempt, both Chrome and Firefox. This is why I think it's something to do with our Cylance policy that is preventing the export from completing
I'm on a REALLY tight government workstation and even I can use SAML-tracer.. Why not try and disable your security tool for a second and see if it makes any difference, instead of asking us to debug the indebuggable/non-reproducible issue?
Ask yourself how you can rule out your environment, instead of asking the community to rule out an environment that's a complete black-box for them ;)
Yep, as Tim said it's really hard to guess what the problem may be. 🤔
I think it's really worth a try disabling Cylance for a moment. Does it log something when re-enable it and try the export again? Does it prevent other downloads or similar things, too?
That's what I was somewhat obscurely asking for in my initial post. Are there any paths your extensions runs from I can try to exclude from our EPP?
What do you mean by paths? This add-on is all javascript..
I ask because EPPs can block scripts based upon policies, and I need the path the script runs from to exclude said script(s)
You could try the following:
about:support
into Firefox's addressbar. There you'll find an extensions-section. <SAML-tracer extension ID>.xpi
Good luck 😀👍
Did this work out for you, @michaellewis259? Or did you give up on it? 😕
Nothing seems to be working, no exclusion I make (that's acceptable from a security standpoint) helps. I'll just use a VM or something. I appreciate the assist, and sorry for the wasted time.
Even though this issue is closed I just want to add that I have the exact same issue
@si-heger Are you using the same security product as the OP? If you can help us get to the problematic code, we can try to fix it..
@tvdijen We are not using the same products but similar stuff like Crowdstrike Falcon and Tenable Nessus. Getting the code is difficult as I am not a programmer :) If you can send me an instruction on how to get more details I can do that
See if you can get things to work by following @khlr 's suggestions. I'm not familiar with Crowdstrike or Tenable, but I'm sure it produces logs if it blocks something..
I have the same issue, on my VM, just normal windows 10 without any antivirus installed.
on the saml-tracer, (f12), console>
Uncaught SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
createFromJSON moz-extension://bf62048e-a85b-45ab-9121-67d45272d2fb/src/SAMLTraceIO.js:180
enrichWithResponse moz-extension://bf62048e-a85b-45ab-9121-67d45272d2fb/src/SAMLTraceIO.js:184
reqscopy moz-extension://bf62048e-a85b-45ab-9121-67d45272d2fb/src/SAMLTraceIO.js:192
perform moz-extension://bf62048e-a85b-45ab-9121-67d45272d2fb/src/SAMLTraceIO.js:190
exportRequests moz-extension://bf62048e-a85b-45ab-9121-67d45272d2fb/src/SAMLTraceIO.js:26
createExportResult moz-extension://bf62048e-a85b-45ab-9121-67d45272d2fb/src/exportDialog.js:66
setupContent moz-extension://bf62048e-a85b-45ab-9121-67d45272d2fb/src/exportDialog.js:60
bindButtons moz-extension://bf62048e-a85b-45ab-9121-67d45272d2fb/src/ui.js:95
Anyway , what I tested was :
If I access the page that prompt for Warning: Potential Security Risk Ahead, SEC_ERROR_UNKNOWN_ISSUER
, then the export will be null
If I have already accept the risk and conitnue
previously, then the export works as expected
I was able to replicate this as well, based on what info @slowerogue provided above.
I simply triggered an AuthnRequest to an IDP that had a self-signed certificate loaded. I was unable to export the AuthnRequest in SAML-Tracer. Even trying the export again after clicking "Accept Risk and Continue" I was unable to export.
All of this testing was performed in my lab environment with no security solution in place, and given the issue seems to have cropped up for sites with self-signed certs (and hence the "Potential Security Risk" warning), I am going to venture and guess that this may be related to Firefox security impositions? I use SAML-Tracer frequently with in-progress or dev sites with self-signed HTTPS certificates, but I don't think I've ever tried exporting one of them.
Strictly speaking, I'm not sure that this is 100% related to the issue as originally brought up by @michaellewis259, but it very well could be, and certainly does seem to be repeatable. My deep suspicion here is that this is the result of restrictions placed on the WebExtension when the security warning is triggered for the self-signed cert.
I also just noticed that we're dead-threading here... I'm going to post my comment above on the open issue #69.
I'm having issues with exporting the trace. It doesn't matter if I mask/exclude values or not, the resulting file shows as null. This is happening in both Firefox and Chrome, which leads me to believe there is something I need to allow with one of my security tools, but nothing is showing up in their various consoles. Do you have any ideas as to what is going on?