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 #include "net/http/http_util.h"
     11 
     12 namespace net {
     13 
     14 namespace {
     15 
     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 
     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