1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/http/http_log_util.h"
#include <string_view>
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/http_auth_scheme.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/log/net_log_with_source.h"
namespace net {
namespace {
bool ShouldRedactChallenge(HttpAuthChallengeTokenizer* challenge) {
// 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 (challenge->challenge_text().find(',') != std::string::npos)
return false;
const std::string& scheme = challenge->auth_scheme();
// Invalid input.
if (scheme.empty())
return false;
// Ignore Basic and Digest authentication challenges, as they contain
// public information.
if (scheme == kBasicAuthScheme || scheme == kDigestAuthScheme)
return false;
return true;
}
} // namespace
std::string ElideHeaderValueForNetLog(NetLogCaptureMode capture_mode,
std::string_view header,
std::string_view value) {
std::string_view redact;
if (!NetLogCaptureIncludesSensitive(capture_mode)) {
if (base::EqualsCaseInsensitiveASCII(header, "set-cookie") ||
base::EqualsCaseInsensitiveASCII(header, "set-cookie2") ||
base::EqualsCaseInsensitiveASCII(header, "cookie") ||
base::EqualsCaseInsensitiveASCII(header, "authorization") ||
base::EqualsCaseInsensitiveASCII(header, "proxy-authorization")) {
redact = value;
} else if (base::EqualsCaseInsensitiveASCII(header, "www-authenticate") ||
base::EqualsCaseInsensitiveASCII(header, "proxy-authenticate")) {
// Look for authentication information from data received from the server
// in multi-round Negotiate authentication.
HttpAuthChallengeTokenizer challenge(value);
if (ShouldRedactChallenge(&challenge)) {
redact = challenge.params();
}
}
}
if (redact.empty()) {
return std::string(value);
}
// Create string_views that contain the part of `value` before the `redact`
// substring, and the value after it. Need to use the data() field of the two
// string_views to figure out where `redact` appears within `value`.
size_t redact_offset = redact.data() - value.data();
std::string_view value_before_redact = value.substr(0, redact_offset);
std::string_view value_after_redact =
value.substr(redact_offset + redact.length());
return base::StrCat({value_before_redact,
base::StringPrintf("[%ld bytes were stripped]",
static_cast<long>(redact.length())),
value_after_redact});
}
NET_EXPORT void NetLogResponseHeaders(const NetLogWithSource& net_log,
NetLogEventType type,
const HttpResponseHeaders* headers) {
net_log.AddEvent(type, [&](NetLogCaptureMode capture_mode) {
return headers->NetLogParams(capture_mode);
});
}
void NetLogRequestHeaders(const NetLogWithSource& net_log,
NetLogEventType type,
const std::string& request_line,
const HttpRequestHeaders* headers) {
net_log.AddEvent(type, [&](NetLogCaptureMode capture_mode) {
return headers->NetLogParams(request_line, capture_mode);
});
}
} // namespace net
|