• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "net/http/http_util.h"
11 
12 namespace net {
13 
14 namespace {
15 
ShouldRedactChallenge(HttpAuthChallengeTokenizer * challenge)16 bool ShouldRedactChallenge(HttpAuthChallengeTokenizer* challenge) {
17   // Ignore lines with commas, as they may contain lists of schemes, and
18   // the information we want to hide is Base64 encoded, so has no commas.
19   if (challenge->challenge_text().find(',') != std::string::npos)
20     return false;
21 
22   std::string scheme = base::StringToLowerASCII(challenge->scheme());
23   // Invalid input.
24   if (scheme.empty())
25     return false;
26 
27   // Ignore Basic and Digest authentication challenges, as they contain
28   // public information.
29   if (scheme == "basic" || scheme == "digest")
30     return false;
31 
32   return true;
33 }
34 
35 }  // namespace
36 
ElideHeaderValueForNetLog(NetLog::LogLevel log_level,const std::string & header,const std::string & value)37 std::string ElideHeaderValueForNetLog(NetLog::LogLevel log_level,
38                                       const std::string& header,
39                                       const std::string& value) {
40   std::string::const_iterator redact_begin = value.begin();
41   std::string::const_iterator redact_end = value.begin();
42 
43   if (redact_begin == redact_end &&
44       log_level >= NetLog::LOG_STRIP_PRIVATE_DATA) {
45 
46     // Note: this logic should be kept in sync with stripCookiesAndLoginInfo in
47     // chrome/browser/resources/net_internals/log_view_painter.js.
48 
49     if (!base::strcasecmp(header.c_str(), "set-cookie") ||
50         !base::strcasecmp(header.c_str(), "set-cookie2") ||
51         !base::strcasecmp(header.c_str(), "cookie") ||
52         !base::strcasecmp(header.c_str(), "authorization") ||
53         !base::strcasecmp(header.c_str(), "proxy-authorization")) {
54       redact_begin = value.begin();
55       redact_end = value.end();
56     } else if (!base::strcasecmp(header.c_str(), "www-authenticate") ||
57                !base::strcasecmp(header.c_str(), "proxy-authenticate")) {
58       // Look for authentication information from data received from the server
59       // in multi-round Negotiate authentication.
60       HttpAuthChallengeTokenizer challenge(value.begin(), value.end());
61       if (ShouldRedactChallenge(&challenge)) {
62         redact_begin = challenge.params_begin();
63         redact_end = challenge.params_end();
64       }
65     }
66   }
67 
68   if (redact_begin == redact_end)
69     return value;
70 
71   return std::string(value.begin(), redact_begin) +
72       base::StringPrintf("[%ld bytes were stripped]",
73                          static_cast<long>(redact_end - redact_begin)) +
74       std::string(redact_end, value.end());
75 }
76 
77 }  // namespace net
78