Commit 65f9c3dc authored by Eric Roman's avatar Eric Roman Committed by Commit Bot

Don't strip cookies/auth when viewing chrome://net-internals/#events

It used to be that you could select whether to strip cookies and auth
headers for export, with the default being to strip.

The ability to export was since removed, which also lost the option to
disable stripping. This change removes stripping all together.

(With stripping removed from net-internals#events, users can
inadvertently expose data when copy-pasting visualizations of the net
log, however this is considered out of scope.)

Ultimately this won't matter as net-internals#events is slated for
eventual removal (crbug.com/678391).

Bug: 777473
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I7833e3c1f15feab8acf8609a82cbc9e2f2dae422
Reviewed-on: https://chromium-review.googlesource.com/747864Reviewed-by: default avatarHelen Li <xunjieli@chromium.org>
Commit-Queue: Eric Roman <eroman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#513241}
parent f0655b36
......@@ -143,13 +143,6 @@ var EventsView = (function() {
this.setFilter_(this.getFilterText_());
},
/**
* Updates text in the details view when privacy stripping is toggled.
*/
onPrivacyStrippingChanged: function() {
this.invalidateDetailsView_();
},
/**
* Updates text in the details view when time display mode is toggled.
*/
......
......@@ -9,8 +9,7 @@ log_util = (function() {
* Creates a new log dump. |events| is a list of all events, |polledData| is
* an object containing the results of each poll, |tabData| is an object
* containing data for individual tabs, |date| is the time the dump was
* created, as a formatted string, and |privacyStripping| is whether or not
* private information should be removed from the generated dump.
* created, as a formatted string.
*
* Returns the new log dump as an object. Resulting object may have a null
* |numericDate|.
......@@ -32,11 +31,7 @@ log_util = (function() {
* tabs not present on the OS the log is from.
*/
function createLogDump(
userComments, constants, events, polledData, tabData, numericDate,
privacyStripping) {
if (privacyStripping)
events = events.map(stripPrivacyInfo);
userComments, constants, events, polledData, tabData, numericDate) {
var logDump = {
'userComments': userComments,
'constants': constants,
......@@ -57,12 +52,11 @@ log_util = (function() {
* Creates a full log dump using |polledData| and the return value of each
* tab's saveState function and passes it to |callback|.
*/
function onUpdateAllCompleted(
userComments, callback, privacyStripping, polledData) {
function onUpdateAllCompleted(userComments, callback, polledData) {
var logDump = createLogDump(
userComments, Constants,
EventsTracker.getInstance().getAllCapturedEvents(), polledData,
getTabData_(), timeutil.getCurrentTime(), privacyStripping);
getTabData_(), timeutil.getCurrentTime());
callback(JSON.stringify(logDump));
}
......@@ -71,9 +65,9 @@ log_util = (function() {
* loaded. Once a log dump has been created, |callback| is passed the dumped
* text as a string.
*/
function createLogDumpAsync(userComments, callback, privacyStripping) {
g_browser.updateAllInfo(onUpdateAllCompleted.bind(
null, userComments, callback, privacyStripping));
function createLogDumpAsync(userComments, callback) {
g_browser.updateAllInfo(
onUpdateAllCompleted.bind(null, userComments, callback));
}
/**
......
......@@ -6,7 +6,6 @@
var createLogEntryTablePrinter;
var proxySettingsToString;
var stripPrivacyInfo;
// Start of anonymous namespace.
(function() {
......@@ -22,8 +21,7 @@ function canCollapseBeginWithEnd(beginEntry) {
* Creates a TablePrinter for use by the above two functions. baseTime is
* the time relative to which other times are displayed.
*/
createLogEntryTablePrinter = function(
logEntries, privacyStripping, baseTime, logCreationTime) {
createLogEntryTablePrinter = function(logEntries, baseTime, logCreationTime) {
var entries = LogGroupEntry.createArrayFrom(logEntries);
var tablePrinter = new TablePrinter();
var parameterOutputter = new ParameterOutputter(tablePrinter);
......@@ -66,7 +64,7 @@ createLogEntryTablePrinter = function(
if (typeof entry.orig.params == 'object') {
// Those 5 skipped cells are: two for "t=", and three for "st=".
tablePrinter.setNewRowCellIndent(5 + entry.getDepth());
writeParameters(entry.orig, privacyStripping, parameterOutputter);
writeParameters(entry.orig, parameterOutputter);
tablePrinter.setNewRowCellIndent(0);
}
......@@ -240,15 +238,10 @@ var ParameterOutputter = (function() {
* Certain event types have custom pretty printers. Everything else will
* default to a JSON-like format.
*/
function writeParameters(entry, privacyStripping, out) {
if (privacyStripping) {
// If privacy stripping is enabled, remove data as needed.
entry = stripPrivacyInfo(entry);
} else {
// If headers are in an object, convert them to an array for better
// display.
entry = reformatHeaders(entry);
}
function writeParameters(entry, out) {
// If headers are in an object, convert them to an array for better
// display.
entry = reformatHeaders(entry);
// Use any parameter writer available for this event type.
var paramsWriter = getParameterWriterForEventType(entry.type);
......@@ -441,131 +434,6 @@ function reformatHeaders(entry) {
return entry;
}
/**
* Removes a cookie or unencrypted login information from a single HTTP header
* line, if present, and returns the modified line. Otherwise, just returns
* the original line.
*
* Note: this logic should be kept in sync with
* net::ElideHeaderValueForNetLog in net/http/http_log_util.cc.
*/
function stripCookieOrLoginInfo(line) {
var patterns = [
// Cookie patterns
/^set-cookie: /i, /^set-cookie2: /i, /^cookie: /i,
// Unencrypted authentication patterns
/^authorization: \S*\s*/i, /^proxy-authorization: \S*\s*/i
];
// Prefix will hold the first part of the string that contains no private
// information. If null, no part of the string contains private
// information.
var prefix = null;
for (var i = 0; i < patterns.length; i++) {
var match = patterns[i].exec(line);
if (match != null) {
prefix = match[0];
break;
}
}
// Look for authentication information from data received from the server in
// multi-round Negotiate authentication.
if (prefix === null) {
var challengePatterns =
[/^www-authenticate: (\S*)\s*/i, /^proxy-authenticate: (\S*)\s*/i];
for (var i = 0; i < challengePatterns.length; i++) {
var match = challengePatterns[i].exec(line);
if (!match)
continue;
// If there's no data after the scheme name, do nothing.
if (match[0].length == line.length)
break;
// Ignore lines with commas, as they may contain lists of schemes, and
// the information we want to hide is Base64 encoded, so has no commas.
if (line.indexOf(',') >= 0)
break;
// Ignore Basic and Digest authentication challenges, as they contain
// public information.
if (/^basic$/i.test(match[1]) || /^digest$/i.test(match[1]))
break;
prefix = match[0];
break;
}
}
if (prefix) {
var suffix = line.slice(prefix.length);
// If private information has already been removed, keep the line as-is.
// This is often the case when viewing a loaded log.
if (suffix.search(/^\[[0-9]+ bytes were stripped\]$/) == -1) {
return prefix + '[' + suffix.length + ' bytes were stripped]';
}
}
return line;
}
/**
* Remove debug data from HTTP/2 GOAWAY frame due to privacy considerations,
* see
* https://httpwg.github.io/specs/rfc7540.html#GOAWAY.
*
* Note: this logic should be kept in sync with
* net::ElideGoAwayDebugDataForNetLog in net/http/http_log_util.cc.
*/
function stripGoAwayDebugData(value) {
return '[' + value.length + ' bytes were stripped]';
}
/**
* If |entry| has headers, returns a copy of |entry| with all cookie and
* unencrypted login text removed. Otherwise, returns original |entry|
* object.
* This is needed so that JSON log dumps can be made without affecting the
* source data. Converts headers stored in objects to arrays.
*/
stripPrivacyInfo = function(entry) {
if (!entry.params) {
return entry;
}
if (entry.type == EventType.HTTP2_SESSION_GOAWAY &&
entry.params.debug_data != undefined) {
// Duplicate the top level object, and |entry.params|. All other fields
// are
// just pointers to the original values, as they won't be modified, other
// than |entry.params.debug_data|.
entry = shallowCloneObject(entry);
entry.params = shallowCloneObject(entry.params);
entry.params.debug_data = stripGoAwayDebugData(entry.params.debug_data);
return entry;
}
if (entry.params.headers === undefined ||
!(entry.params.headers instanceof Object)) {
return entry;
}
// Make sure entry's headers are in an array.
entry = reformatHeaders(entry);
// Duplicate the top level object, and |entry.params|. All other fields are
// just pointers to the original values, as they won't be modified, other
// than
// |entry.params.headers|.
entry = shallowCloneObject(entry);
entry.params = shallowCloneObject(entry.params);
entry.params.headers = entry.params.headers.map(stripCookieOrLoginInfo);
return entry;
};
/**
* Outputs the request header parameters of |entry| to |out|.
*/
......
......@@ -125,10 +125,8 @@ var MainView = (function() {
this.stopCapturing();
if (opt_fileName != undefined) {
// If there's a file name, a log file was loaded, so swap out the status
// bar to indicate we're no longer capturing events. Also disable
// hiding cookies, so if the log dump has them, they'll be displayed.
// bar to indicate we're no longer capturing events.
this.topBarView_.switchToSubView('loaded').setFileName(opt_fileName);
SourceTracker.getInstance().setPrivacyStripping(false);
} else {
// Otherwise, the "Stop Capturing" button was presumably pressed.
// Don't disable hiding cookies, so created log dumps won't have them,
......
......@@ -335,7 +335,7 @@ var SourceEntry = (function() {
*/
createTablePrinter: function() {
return createLogEntryTablePrinter(
this.entries_, SourceTracker.getInstance().getPrivacyStripping(),
this.entries_,
SourceTracker.getInstance().getUseRelativeTimes() ?
timeutil.getBaseTime() :
0,
......
......@@ -18,11 +18,6 @@ var SourceTracker = (function() {
// Observers that only want to receive lists of updated SourceEntries.
this.sourceEntryObservers_ = [];
// True when cookies and authentication information should be removed from
// displayed events. When true, such information should be hidden from
// all pages.
this.privacyStripping_ = true;
// True when times should be displayed as milliseconds since the first
// event, as opposed to milliseconds since January 1, 1970.
this.useRelativeTimes_ = true;
......@@ -134,26 +129,6 @@ var SourceTracker = (function() {
this.sourceEntryObservers_[i].onAllSourceEntriesDeleted();
},
/**
* Sets the value of |privacyStripping_| and informs log observers
* of the change.
*/
setPrivacyStripping: function(privacyStripping) {
this.privacyStripping_ = privacyStripping;
for (var i = 0; i < this.sourceEntryObservers_.length; ++i) {
if (this.sourceEntryObservers_[i].onPrivacyStrippingChanged)
this.sourceEntryObservers_[i].onPrivacyStrippingChanged();
}
},
/**
* Returns whether or not cookies and authentication information should be
* displayed for events that contain them.
*/
getPrivacyStripping: function() {
return this.privacyStripping_;
},
/**
* Sets the value of |useRelativeTimes_| and informs log observers
* of the change.
......@@ -176,12 +151,10 @@ var SourceTracker = (function() {
/**
* Adds a listener of SourceEntries. |observer| will be called back when
* SourceEntries are added or modified, source entries are deleted, or
* privacy stripping changes:
* SourceEntries are added or modified or source entries are deleted.
*
* observer.onSourceEntriesUpdated(sourceEntries)
* observer.onAllSourceEntriesDeleted()
* observer.onPrivacyStrippingChanged()
*/
addSourceEntryObserver: function(observer) {
this.sourceEntryObservers_.push(observer);
......
......@@ -34,8 +34,6 @@ CreateAndLoadLogTask.prototype = {
* Starts creating the log dump.
*/
start: function() {
this.initialPrivacyStripping_ =
SourceTracker.getInstance().getPrivacyStripping();
log_util.createLogDumpAsync(this.userComments_,
this.onLogDumpCreated.bind(this), true);
},
......@@ -46,10 +44,7 @@ CreateAndLoadLogTask.prototype = {
* @param {string} logDumpText Log dump, as a string.
*/
onLogDumpCreated: function(logDumpText) {
expectEquals(this.initialPrivacyStripping_,
SourceTracker.getInstance().getPrivacyStripping());
expectEquals('Log loaded.', log_util.loadLogFile(logDumpText, 'log.txt'));
expectFalse(SourceTracker.getInstance().getPrivacyStripping());
NetInternalsTest.expectStatusViewNodeVisible(LoadedStatusView.MAIN_BOX_ID);
......@@ -123,7 +118,6 @@ GetNetLogFileContentsAndLoadLogTask.prototype = {
*/
onLogReceived_: function(logDumpText) {
assertEquals('string', typeof logDumpText);
expectTrue(SourceTracker.getInstance().getPrivacyStripping());
var expectedResult = 'Log loaded.';
......@@ -134,7 +128,6 @@ GetNetLogFileContentsAndLoadLogTask.prototype = {
logDumpText = logDumpText.substring(0, logDumpText.length - this.truncate_);
expectEquals(expectedResult, log_util.loadLogFile(logDumpText, 'log.txt'));
expectFalse(SourceTracker.getInstance().getPrivacyStripping());
NetInternalsTest.expectStatusViewNodeVisible(LoadedStatusView.MAIN_BOX_ID);
......@@ -201,11 +194,6 @@ function checkViewsAfterNetLogFileLoaded() {
NetInternalsTest.checkTabLinkVisibility(tabVisibilityState, false);
}
function checkPrivacyStripping(expectedValue) {
expectEquals(expectedValue,
SourceTracker.getInstance().getPrivacyStripping());
}
/**
* Checks the currently active view.
* @param {string} id ID of the view that should be active.
......@@ -222,7 +210,6 @@ function checkActiveView(id) {
*/
TEST_F('NetInternalsTest', 'netInternalsLogUtilExportImport', function() {
expectFalse(g_browser.isDisabled());
expectTrue(SourceTracker.getInstance().getPrivacyStripping());
NetInternalsTest.expectStatusViewNodeVisible(CaptureStatusView.MAIN_BOX_ID);
var taskQueue = new NetInternalsTest.TaskQueue(true);
......@@ -269,7 +256,6 @@ TEST_F('NetInternalsTest', 'netInternalsLogUtilStopCapturing', function() {
NetInternalsTest.expectStatusViewNodeVisible.bind(
null, HaltedStatusView.MAIN_BOX_ID));
taskQueue.addFunctionTask(checkViewsAfterLogLoaded);
taskQueue.addFunctionTask(checkPrivacyStripping.bind(null, true));
taskQueue.addFunctionTask(checkActiveView.bind(null, EventsView.TAB_ID));
taskQueue.run();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment