1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/http/http_log_util.h" 6 7 #include "base/strings/string_util.h" 8 #include "base/strings/stringprintf.h" 9 #include "net/http/http_auth_challenge_tokenizer.h" 10 11 namespace net { 12 13 namespace { 14 15 bool ShouldRedactChallenge(HttpAuthChallengeTokenizer* challenge) { 16 // Ignore lines with commas, as they may contain lists of schemes, and 17 // the information we want to hide is Base64 encoded, so has no commas. 18 if (challenge->challenge_text().find(',') != std::string::npos) 19 return false; 20 21 std::string scheme = StringToLowerASCII(challenge->scheme()); 22 // Invalid input. 23 if (scheme.empty()) 24 return false; 25 26 // Ignore Basic and Digest authentication challenges, as they contain 27 // public information. 28 if (scheme == "basic" || scheme == "digest") 29 return false; 30 31 return true; 32 } 33 34 } // namespace 35 36 std::string ElideHeaderValueForNetLog(NetLog::LogLevel log_level, 37 const std::string& header, 38 const std::string& value) { 39 #if defined(SPDY_PROXY_AUTH_ORIGIN) 40 if (!base::strcasecmp(header.c_str(), "proxy-authorization") || 41 !base::strcasecmp(header.c_str(), "proxy-authenticate")) { 42 return "[elided]"; 43 } 44 #endif 45 46 if (log_level < NetLog::LOG_STRIP_PRIVATE_DATA) 47 return value; 48 49 // Note: this logic should be kept in sync with stripCookiesAndLoginInfo in 50 // chrome/browser/resources/net_internals/log_view_painter.js. 51 52 std::string::const_iterator redact_begin = value.begin(); 53 std::string::const_iterator redact_end = value.begin(); 54 if (!base::strcasecmp(header.c_str(), "set-cookie") || 55 !base::strcasecmp(header.c_str(), "set-cookie2") || 56 !base::strcasecmp(header.c_str(), "cookie") || 57 !base::strcasecmp(header.c_str(), "authorization") || 58 !base::strcasecmp(header.c_str(), "proxy-authorization")) { 59 redact_begin = value.begin(); 60 redact_end = value.end(); 61 } else if (!base::strcasecmp(header.c_str(), "www-authenticate") || 62 !base::strcasecmp(header.c_str(), "proxy-authenticate")) { 63 // Look for authentication information from data received from the server in 64 // multi-round Negotiate authentication. 65 HttpAuthChallengeTokenizer challenge(value.begin(), value.end()); 66 if (ShouldRedactChallenge(&challenge)) { 67 redact_begin = challenge.params_begin(); 68 redact_end = challenge.params_end(); 69 } 70 } 71 72 if (redact_begin == redact_end) 73 return value; 74 75 return std::string(value.begin(), redact_begin) + 76 base::StringPrintf("[%ld bytes were stripped]", 77 static_cast<long>(redact_end - redact_begin)) + 78 std::string(redact_end, value.end()); 79 } 80 81 } // namespace net 82