Home | History | Annotate | Download | only in http
      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