// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/network/cross_origin_read_blocking.h"

#include <stddef.h>

#include <algorithm>
#include <set>
#include <string>
#include <unordered_set>
#include <vector>

#include "base/command_line.h"
#include "base/containers/flat_set.h"
#include "base/feature_list.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "net/base/mime_sniffer.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "services/network/cross_origin_resource_policy.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/resource_response_info.h"

using base::StringPiece;
using MimeType = network::CrossOriginReadBlocking::MimeType;
using SniffingResult = network::CrossOriginReadBlocking::SniffingResult;

namespace network {

namespace {

// MIME types
const char kTextHtml[] = "text/html";
const char kTextXml[] = "text/xml";
const char kAppXml[] = "application/xml";
const char kAppJson[] = "application/json";
const char kImageSvg[] = "image/svg+xml";
const char kDashVideo[] = "application/dash+xml";  // https://crbug.com/947498
const char kTextJson[] = "text/json";
const char kTextPlain[] = "text/plain";
// TODO(lukasza): Remove kJsonProtobuf once this MIME type is not used in
// practice.  See also https://crbug.com/826756#c3
const char kJsonProtobuf[] = "application/json+protobuf";

// MIME type suffixes
const char kJsonSuffix[] = "+json";
const char kXmlSuffix[] = "+xml";

void AdvancePastWhitespace(StringPiece* data) {
  size_t offset = data->find_first_not_of(" \t\r\n");
  if (offset == base::StringPiece::npos) {
    // |data| was entirely whitespace.
    data->clear();
  } else {
    data->remove_prefix(offset);
  }
}

// Returns kYes if |data| starts with one of the string patterns in
// |signatures|, kMaybe if |data| is a prefix of one of the patterns in
// |signatures|, and kNo otherwise.
//
// When kYes is returned, the matching prefix is erased from |data|.
SniffingResult MatchesSignature(StringPiece* data,
                                const StringPiece signatures[],
                                size_t arr_size,
                                base::CompareCase compare_case) {
  for (size_t i = 0; i < arr_size; ++i) {
    if (signatures[i].length() <= data->length()) {
      if (base::StartsWith(*data, signatures[i], compare_case)) {
        // When |signatures[i]| is a prefix of |data|, it constitutes a match.
        // Strip the matching characters, and return.
        data->remove_prefix(signatures[i].length());
        return CrossOriginReadBlocking::kYes;
      }
    } else {
      if (base::StartsWith(signatures[i], *data, compare_case)) {
        // When |data| is a prefix of |signatures[i]|, that means that
        // subsequent bytes in the stream could cause a match to occur.
        return CrossOriginReadBlocking::kMaybe;
      }
    }
  }
  return CrossOriginReadBlocking::kNo;
}

size_t FindFirstJavascriptLineTerminator(const base::StringPiece& hay,
                                         size_t pos) {
  // https://www.ecma-international.org/ecma-262/8.0/index.html#prod-LineTerminator
  // defines LineTerminator ::= <LF> | <CR> | <LS> | <PS>.
  //
  // https://www.ecma-international.org/ecma-262/8.0/index.html#sec-line-terminators
  // defines <LF>, <CR>, <LS> ::= "\u2028", <PS> ::= "\u2029".
  //
  // In UTF8 encoding <LS> is 0xE2 0x80 0xA8 and <PS> is 0xE2 0x80 0xA9.
  while (true) {
    pos = hay.find_first_of("\n\r\xe2", pos);
    if (pos == base::StringPiece::npos)
      break;

    if (hay[pos] != '\xe2') {
      DCHECK(hay[pos] == '\r' || hay[pos] == '\n');
      break;
    }

    // TODO(lukasza): Prevent matching 3 bytes that span/straddle 2 UTF8
    // characters.
    base::StringPiece substr = hay.substr(pos);
    if (substr.starts_with("\u2028") || substr.starts_with("\u2029"))
      break;

    pos++;  // Skip the \xe2 character.
  }
  return pos;
}

// Checks if |data| starts with an HTML comment (i.e. with "<!-- ... -->").
// - If there is a valid, terminated comment then returns kYes.
// - If there is a start of a comment, but the comment is not completed (e.g.
//   |data| == "<!-" or |data| == "<!-- not terminated yet") then returns
//   kMaybe.
// - Returns kNo otherwise.
//
// Mutates |data| to advance past the comment when returning kYes.  Note that
// SingleLineHTMLCloseComment ECMAscript rule is taken into account which means
// that characters following an HTML comment are consumed up to the nearest line
// terminating character.
SniffingResult MaybeSkipHtmlComment(StringPiece* data) {
  constexpr StringPiece kStartString = "<!--";
  if (!data->starts_with(kStartString)) {
    if (kStartString.starts_with(*data))
      return CrossOriginReadBlocking::kMaybe;
    return CrossOriginReadBlocking::kNo;
  }

  constexpr StringPiece kEndString = "-->";
  size_t end_of_html_comment = data->find(kEndString, kStartString.length());
  if (end_of_html_comment == StringPiece::npos)
    return CrossOriginReadBlocking::kMaybe;
  end_of_html_comment += kEndString.length();

  // Skipping until the first line terminating character.  See
  // https://crbug.com/839945 for the motivation behind this.
  size_t end_of_line =
      FindFirstJavascriptLineTerminator(*data, end_of_html_comment);
  if (end_of_line == base::StringPiece::npos)
    return CrossOriginReadBlocking::kMaybe;

  // Found real end of the combined HTML/JS comment.
  data->remove_prefix(end_of_line);
  return CrossOriginReadBlocking::kYes;
}

// Removes headers that should be blocked in cross-origin case.
//
// Note that corbSanitizedResponse in https://fetch.spec.whatwg.org/#main-fetch
// has an empty list of headers, but the code below doesn't remove all the
// headers for improved user experience - for better error messages for CORS.
// See also https://github.com/whatwg/fetch/pull/686#issuecomment-383711732 and
// the http/tests/xmlhttprequest/origin-exact-matching/07.html layout test.
//
// Note that CORB doesn't block responses allowed through CORS - this means
// that the list of allowed headers below doesn't have to consider header
// names listed in the Access-Control-Expose-Headers header.
void BlockResponseHeaders(
    const scoped_refptr<net::HttpResponseHeaders>& headers) {
  DCHECK(headers);
  std::unordered_set<std::string> names_of_headers_to_remove;

  size_t it = 0;
  std::string name;
  std::string value;
  while (headers->EnumerateHeaderLines(&it, &name, &value)) {
    // Don't remove CORS headers - doing so would lead to incorrect error
    // messages for CORS-blocked responses (e.g. Blink would say "[...] No
    // 'Access-Control-Allow-Origin' header is present [...]" instead of saying
    // something like "[...] Access-Control-Allow-Origin' header has a value
    // 'http://www2.localhost:8000' that is not equal to the supplied origin
    // [...]").
    if (base::StartsWith(name, "Access-Control-",
                         base::CompareCase::INSENSITIVE_ASCII)) {
      continue;
    }

    // Remove all other headers.
    names_of_headers_to_remove.insert(base::ToLowerASCII(name));
  }

  headers->RemoveHeaders(names_of_headers_to_remove);
}

std::set<int>& GetPluginProxyingProcesses() {
  static base::NoDestructor<std::set<int>> set;
  return *set;
}

bool ShouldEnforceInitiatorLock() {
  return base::FeatureList::IsEnabled(network::features::kNetworkService);
}

const base::flat_set<std::string>& GetNeverSniffedMimeTypes() {
  // The types below may be blocked by CORB without any confirmation sniffing
  // (in contrast to HTML/JSON/XML which require confirmation sniffing because
  // images, scripts, etc. are frequently mislabelled by http servers as
  // HTML/JSON/XML).
  //
  // The list below has been populated based on most commonly used content types
  // according to HTTP Archive - see:
  // https://github.com/whatwg/fetch/issues/860#issuecomment-457330454
  //
  // TODO(lukasza): https://crbug.com/802836: Add application/msword,
  // application/pdf and text/csv to the list of content types below after
  // https://crbug.com/929300 is resolved.  See also the CR comment in
  // https://crrev.com/c/1604244/3/services/network/cross_origin_read_blocking.cc#229
  //
  // TODO(lukasza): https://crbug.com/802836#c11: Add
  // application/signed-exchange.
  static const base::NoDestructor<base::flat_set<std::string>> s_types([] {
    const char* kMimeTypes[] = {
        "application/x-gzip",
        "application/x-protobuf",
        "application/zip",
    };
    std::vector<std::string> types;
    types.reserve(base::size(kMimeTypes));
    for (const char* type : kMimeTypes)
      types.push_back(std::string(type));

    // All items need to be lower-case, to support case-insensitive comparisons
    // later.
    DCHECK(std::all_of(types.begin(), types.end(), [](const std::string& s) {
      return s == base::ToLowerASCII(s);
    }));

    base::flat_set<std::string> result(types);
    result.shrink_to_fit();
    return result;
  }());
  return *s_types;
}

}  // namespace

MimeType CrossOriginReadBlocking::GetCanonicalMimeType(
    base::StringPiece mime_type) {
  // Checking for image/svg+xml and application/dash+xml early ensures that they
  // won't get classified as MimeType::kXml by the presence of the "+xml"
  // suffix.
  if (base::LowerCaseEqualsASCII(mime_type, kImageSvg) ||
      base::LowerCaseEqualsASCII(mime_type, kDashVideo))
    return MimeType::kOthers;

  // See also https://mimesniff.spec.whatwg.org/#html-mime-type
  if (base::LowerCaseEqualsASCII(mime_type, kTextHtml))
    return MimeType::kHtml;

  // See also https://mimesniff.spec.whatwg.org/#json-mime-type
  constexpr auto kCaseInsensitive = base::CompareCase::INSENSITIVE_ASCII;
  if (base::LowerCaseEqualsASCII(mime_type, kAppJson) ||
      base::LowerCaseEqualsASCII(mime_type, kTextJson) ||
      base::LowerCaseEqualsASCII(mime_type, kJsonProtobuf) ||
      base::EndsWith(mime_type, kJsonSuffix, kCaseInsensitive)) {
    return MimeType::kJson;
  }

  // See also https://mimesniff.spec.whatwg.org/#xml-mime-type
  if (base::LowerCaseEqualsASCII(mime_type, kAppXml) ||
      base::LowerCaseEqualsASCII(mime_type, kTextXml) ||
      base::EndsWith(mime_type, kXmlSuffix, kCaseInsensitive)) {
    return MimeType::kXml;
  }

  if (base::LowerCaseEqualsASCII(mime_type, kTextPlain))
    return MimeType::kPlain;

  if (base::ContainsKey(GetNeverSniffedMimeTypes(),
                        base::ToLowerASCII(mime_type))) {
    return MimeType::kNeverSniffed;
  }

  return MimeType::kOthers;
}

bool CrossOriginReadBlocking::IsBlockableScheme(const GURL& url) {
  // We exclude ftp:// from here. FTP doesn't provide a Content-Type
  // header which our policy depends on, so we cannot protect any
  // response from FTP servers.
  return url.SchemeIs(url::kHttpScheme) || url.SchemeIs(url::kHttpsScheme);
}

bool CrossOriginReadBlocking::IsValidCorsHeaderSet(
    const url::Origin& frame_origin,
    const std::string& access_control_origin) {
  // Many websites are sending back "\"*\"" instead of "*". This is
  // non-standard practice, and not supported by Chrome. Refer to
  // CrossOriginAccessControl::passesAccessControlCheck().

  // Note that "null" offers no more protection than "*" because it matches any
  // unique origin, such as data URLs. Any origin can thus access it, so don't
  // bother trying to block this case.

  // TODO(dsjang): * is not allowed for the response from a request
  // with cookies. This allows for more than what the renderer will
  // eventually be able to receive, so we won't see illegal cross-site
  // documents allowed by this. We have to find a way to see if this
  // response is from a cookie-tagged request or not in the future.
  if (access_control_origin == "*" || access_control_origin == "null")
    return true;

  return frame_origin.IsSameOriginWith(
      url::Origin::Create(GURL(access_control_origin)));
}

// This function is a slight modification of |net::SniffForHTML|.
SniffingResult CrossOriginReadBlocking::SniffForHTML(StringPiece data) {
  // The content sniffers used by Chrome and Firefox are using "<!--" as one of
  // the HTML signatures, but it also appears in valid JavaScript, considered as
  // well-formed JS by the browser.  Since we do not want to block any JS, we
  // exclude it from our HTML signatures. This can weaken our CORB policy,
  // but we can break less websites.
  //
  // Note that <body> and <br> are not included below, since <b is a prefix of
  // them.
  //
  // TODO(dsjang): parameterize |net::SniffForHTML| with an option that decides
  // whether to include <!-- or not, so that we can remove this function.
  // TODO(dsjang): Once CrossOriginReadBlocking is moved into the browser
  // process, we should do single-thread checking here for the static
  // initializer.
  static const StringPiece kHtmlSignatures[] = {
      StringPiece("<!doctype html"),  // HTML5 spec
      StringPiece("<script"),         // HTML5 spec, Mozilla
      StringPiece("<html"),           // HTML5 spec, Mozilla
      StringPiece("<head"),           // HTML5 spec, Mozilla
      StringPiece("<iframe"),         // Mozilla
      StringPiece("<h1"),             // Mozilla
      StringPiece("<div"),            // Mozilla
      StringPiece("<font"),           // Mozilla
      StringPiece("<table"),          // Mozilla
      StringPiece("<a"),              // Mozilla
      StringPiece("<style"),          // Mozilla
      StringPiece("<title"),          // Mozilla
      StringPiece("<b"),              // Mozilla (note: subsumes <body>, <br>)
      StringPiece("<p")               // Mozilla
  };

  while (data.length() > 0) {
    AdvancePastWhitespace(&data);

    SniffingResult signature_match =
        MatchesSignature(&data, kHtmlSignatures, base::size(kHtmlSignatures),
                         base::CompareCase::INSENSITIVE_ASCII);
    if (signature_match != kNo)
      return signature_match;

    SniffingResult comment_match = MaybeSkipHtmlComment(&data);
    if (comment_match != kYes)
      return comment_match;
  }

  // All of |data| was consumed, without a clear determination.
  return kMaybe;
}

SniffingResult CrossOriginReadBlocking::SniffForXML(base::StringPiece data) {
  // TODO(dsjang): Once CrossOriginReadBlocking is moved into the browser
  // process, we should do single-thread checking here for the static
  // initializer.
  AdvancePastWhitespace(&data);
  static const StringPiece kXmlSignatures[] = {StringPiece("<?xml")};
  return MatchesSignature(&data, kXmlSignatures, base::size(kXmlSignatures),
                          base::CompareCase::SENSITIVE);
}

SniffingResult CrossOriginReadBlocking::SniffForJSON(base::StringPiece data) {
  // Currently this function looks for an opening brace ('{'), followed by a
  // double-quoted string literal, followed by a colon. Importantly, such a
  // sequence is a Javascript syntax error: although the JSON object syntax is
  // exactly Javascript's object-initializer syntax, a Javascript object-
  // initializer expression is not valid as a standalone Javascript statement.
  //
  // TODO(nick): We have to come up with a better way to sniff JSON. The
  // following are known limitations of this function:
  // https://crbug.com/795470/ Support non-dictionary values (e.g. lists)
  enum {
    kStartState,
    kLeftBraceState,
    kLeftQuoteState,
    kEscapeState,
    kRightQuoteState,
  } state = kStartState;

  for (size_t i = 0; i < data.length(); ++i) {
    const char c = data[i];
    if (state != kLeftQuoteState && state != kEscapeState) {
      // Whitespace is ignored (outside of string literals)
      if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
        continue;
    } else {
      // Inside string literals, control characters should result in rejection.
      if ((c >= 0 && c < 32) || c == 127)
        return kNo;
    }

    switch (state) {
      case kStartState:
        if (c == '{')
          state = kLeftBraceState;
        else
          return kNo;
        break;
      case kLeftBraceState:
        if (c == '"')
          state = kLeftQuoteState;
        else
          return kNo;
        break;
      case kLeftQuoteState:
        if (c == '"')
          state = kRightQuoteState;
        else if (c == '\\')
          state = kEscapeState;
        break;
      case kEscapeState:
        // Simplification: don't bother rejecting hex escapes.
        state = kLeftQuoteState;
        break;
      case kRightQuoteState:
        if (c == ':')
          return kYes;
        else
          return kNo;
        break;
    }
  }
  return kMaybe;
}

SniffingResult CrossOriginReadBlocking::SniffForFetchOnlyResource(
    base::StringPiece data) {
  // kScriptBreakingPrefixes contains prefixes that are conventionally used to
  // prevent a JSON response from becoming a valid Javascript program (an attack
  // vector known as XSSI). The presence of such a prefix is a strong signal
  // that the resource is meant to be consumed only by the fetch API or
  // XMLHttpRequest, and is meant to be protected from use in non-CORS, cross-
  // origin contexts like <script>, <img>, etc.
  //
  // These prefixes work either by inducing a syntax error, or inducing an
  // infinite loop. In either case, the prefix must create a guarantee that no
  // matter what bytes follow it, the entire response would be worthless to
  // execute as a <script>.
  static const StringPiece kScriptBreakingPrefixes[] = {
      // Parser breaker prefix.
      //
      // Built into angular.js (followed by a comma and a newline):
      //   https://docs.angularjs.org/api/ng/service/$http
      //
      // Built into the Java Spring framework (followed by a comma and a space):
      //   https://goo.gl/xP7FWn
      //
      // Observed on google.com (without a comma, followed by a newline).
      StringPiece(")]}'"),

      // Apache struts: https://struts.apache.org/plugins/json/#prefix
      StringPiece("{}&&"),

      // Spring framework (historically): https://goo.gl/JYPFAv
      StringPiece("{} &&"),

      // Infinite loops.
      StringPiece("for(;;);"),  // observed on facebook.com
      StringPiece("while(1);"), StringPiece("for (;;);"),
      StringPiece("while (1);"),
  };
  SniffingResult has_parser_breaker = MatchesSignature(
      &data, kScriptBreakingPrefixes, base::size(kScriptBreakingPrefixes),
      base::CompareCase::SENSITIVE);
  if (has_parser_breaker != kNo)
    return has_parser_breaker;

  // A non-empty JSON object also effectively introduces a JS syntax error.
  return SniffForJSON(data);
}

// static
void CrossOriginReadBlocking::SanitizeBlockedResponse(
    const scoped_refptr<network::ResourceResponse>& response) {
  DCHECK(response);
  response->head.content_length = 0;
  if (response->head.headers)
    BlockResponseHeaders(response->head.headers);
}

// static
void CrossOriginReadBlocking::LogAction(Action action) {
  UMA_HISTOGRAM_ENUMERATION("SiteIsolation.XSD.Browser.Action", action);
}

// An interface to enable incremental content sniffing. These are instantiated
// for each each request; thus they can be stateful.
class CrossOriginReadBlocking::ResponseAnalyzer::ConfirmationSniffer {
 public:
  virtual ~ConfirmationSniffer() = default;

  // Called after data is read from the network. |sniffing_buffer| contains the
  // entire response body delivered thus far. To support streaming,
  // |new_data_offset| gives the offset into |sniffing_buffer| at which new data
  // was appended since the last read.
  virtual void OnDataAvailable(base::StringPiece sniffing_buffer,
                               size_t new_data_offset) = 0;

  // Returns true if the return value of IsConfirmedContentType() might change
  // with the addition of more data. Returns false if a final decision is
  // available.
  virtual bool WantsMoreData() const = 0;

  // Returns true if the data has been confirmed to be of the CORB-protected
  // content type that this sniffer is intended to detect.
  virtual bool IsConfirmedContentType() const = 0;

  // Helper for reporting the right UMA.
  virtual bool IsParserBreakerSniffer() const = 0;
};

// A ConfirmationSniffer that wraps one of the sniffing functions from
// network::CrossOriginReadBlocking.
class CrossOriginReadBlocking::ResponseAnalyzer::SimpleConfirmationSniffer
    : public CrossOriginReadBlocking::ResponseAnalyzer::ConfirmationSniffer {
 public:
  // The function pointer type corresponding to one of the available sniffing
  // functions from network::CrossOriginReadBlocking.
  using SnifferFunction =
      decltype(&network::CrossOriginReadBlocking::SniffForHTML);

  explicit SimpleConfirmationSniffer(SnifferFunction sniffer_function)
      : sniffer_function_(sniffer_function) {}
  ~SimpleConfirmationSniffer() override = default;

  void OnDataAvailable(base::StringPiece sniffing_buffer,
                       size_t new_data_offset) final {
    DCHECK_LE(new_data_offset, sniffing_buffer.length());
    if (new_data_offset == sniffing_buffer.length()) {
      // No new data -- do nothing. This happens at end-of-stream.
      return;
    }
    // The sniffing functions don't support streaming, so with each new chunk of
    // data, call the sniffer on the whole buffer.
    last_sniff_result_ = (*sniffer_function_)(sniffing_buffer);
  }

  bool WantsMoreData() const final {
    // kNo and kYes results are final, meaning that sniffing can stop once they
    // occur. A kMaybe result corresponds to an indeterminate state, that could
    // change to kYes or kNo with more data.
    return last_sniff_result_ == SniffingResult::kMaybe;
  }

  bool IsConfirmedContentType() const final {
    // Only confirm the mime type if an affirmative pattern (e.g. an HTML tag,
    // if using the HTML sniffer) was detected.
    //
    // Note that if the stream ends (or net::kMaxBytesToSniff has been reached)
    // and |last_sniff_result_| is kMaybe, the response is allowed to go
    // through.
    return last_sniff_result_ == SniffingResult::kYes;
  }

  bool IsParserBreakerSniffer() const override { return false; }

 private:
  // The function that actually knows how to sniff for a content type.
  SnifferFunction sniffer_function_;

  // Result of sniffing the data available thus far.
  SniffingResult last_sniff_result_ = SniffingResult::kMaybe;

  DISALLOW_COPY_AND_ASSIGN(SimpleConfirmationSniffer);
};

// A ConfirmationSniffer for parser breakers (fetch-only resources). This logs
// to an UMA histogram whenever it is the reason for a response being blocked.
class CrossOriginReadBlocking::ResponseAnalyzer::FetchOnlyResourceSniffer
    : public CrossOriginReadBlocking::ResponseAnalyzer::
          SimpleConfirmationSniffer {
 public:
  FetchOnlyResourceSniffer()
      : SimpleConfirmationSniffer(
            &network::CrossOriginReadBlocking::SniffForFetchOnlyResource) {}

  bool IsParserBreakerSniffer() const override { return true; }

 private:
  DISALLOW_COPY_AND_ASSIGN(FetchOnlyResourceSniffer);
};

CrossOriginReadBlocking::ResponseAnalyzer::ResponseAnalyzer(
    const net::URLRequest& request,
    const ResourceResponse& response,
    base::Optional<url::Origin> request_initiator_site_lock,
    mojom::FetchRequestMode fetch_request_mode) {
  content_length_ = response.head.content_length;
  http_response_code_ =
      response.head.headers ? response.head.headers->response_code() : 0;
  request_initiator_site_lock_ = request_initiator_site_lock;

  should_block_based_on_headers_ =
      ShouldBlockBasedOnHeaders(fetch_request_mode, request, response);
  if (should_block_based_on_headers_ == kNeedToSniffMore)
    CreateSniffers();
}

CrossOriginReadBlocking::ResponseAnalyzer::~ResponseAnalyzer() = default;

CrossOriginReadBlocking::ResponseAnalyzer::BlockingDecision
CrossOriginReadBlocking::ResponseAnalyzer::ShouldBlockBasedOnHeaders(
    mojom::FetchRequestMode fetch_request_mode,
    const net::URLRequest& request,
    const ResourceResponse& response) {
  // The checks in this method are ordered to rule out blocking in most cases as
  // quickly as possible.  Checks that are likely to lead to returning false or
  // that are inexpensive should be near the top.
  url::Origin target_origin = url::Origin::Create(request.url());

  // Check if |target_origin| seems to match the factory lock in
  // |request_initiator_site_lock_|.  If so, then treat this request as
  // same-origin (even if |request.initiator()| might be cross-origin).  See
  // also https://crbug.com/918660.
  if (VerifyRequestInitiatorLock(request_initiator_site_lock_, target_origin) ==
      InitiatorLockCompatibility::kCompatibleLock) {
    return kAllow;
  }

  // Compute the |initiator| of the request, falling back to a unique origin if
  // there was no initiator or if it was incompatible with the lock. Using a
  // unique origin makes CORB treat the response as cross-origin and thus
  // considers it eligible for blocking (based on content-type, sniffing, etc.).
  url::Origin initiator = GetTrustworthyInitiator(
      ShouldEnforceInitiatorLock() ? request_initiator_site_lock_
                                   : base::nullopt,
      request);

  // Don't block same-origin documents.
  if (initiator.IsSameOriginWith(target_origin))
    return kAllow;

  // Only block documents from HTTP(S) schemes.  Checking the scheme of
  // |target_origin| ensures that we also protect content of blob: and
  // filesystem: URLs if their nested origins have a HTTP(S) scheme.
  if (!IsBlockableScheme(target_origin.GetURL()))
    return kAllow;

  // Allow requests from file:// URLs for now.
  // TODO(creis): Limit this to when the allow_universal_access_from_file_urls
  // preference is set.  See https://crbug.com/789781.
  if (initiator.scheme() == url::kFileScheme)
    return kAllow;

  // Allow the response through if this is a CORS request and the response has
  // valid CORS headers.
  switch (fetch_request_mode) {
    case mojom::FetchRequestMode::kNavigate:
    case mojom::FetchRequestMode::kNoCors:
    case mojom::FetchRequestMode::kSameOrigin:
      break;

    case mojom::FetchRequestMode::kCors:
    case mojom::FetchRequestMode::kCorsWithForcedPreflight:
      std::string cors_header;
      response.head.headers->GetNormalizedHeader("access-control-allow-origin",
                                                 &cors_header);
      if (IsValidCorsHeaderSet(initiator, cors_header))
        return kAllow;
      break;
  }

  // Requests from foo.example.com will consult foo.example.com's service worker
  // first (if one has been registered).  The service worker can handle requests
  // initiated by foo.example.com even if they are cross-origin (e.g. requests
  // for bar.example.com).  This is okay and should not be blocked by CORB,
  // unless the initiator opted out of CORS / opted into receiving an opaque
  // response.  See also https://crbug.com/803672.
  if (response.head.was_fetched_via_service_worker) {
    switch (response.head.response_type) {
      case network::mojom::FetchResponseType::kBasic:
      case network::mojom::FetchResponseType::kCors:
      case network::mojom::FetchResponseType::kDefault:
      case network::mojom::FetchResponseType::kError:
        // Non-opaque responses shouldn't be blocked.
        return kAllow;
      case network::mojom::FetchResponseType::kOpaque:
      case network::mojom::FetchResponseType::kOpaqueRedirect:
        // Opaque responses are eligible for blocking. Continue on...
        break;
    }
  }

  // We intend to block the response at this point.  However, we will usually
  // sniff the contents to confirm the MIME type, to avoid blocking incorrectly
  // labeled JavaScript, JSONP, etc files.
  //
  // Note: if there is a nosniff header, it means we should honor the response
  // mime type without trying to confirm it.
  std::string nosniff_header;
  response.head.headers->GetNormalizedHeader("x-content-type-options",
                                             &nosniff_header);
  bool has_nosniff_header =
      base::LowerCaseEqualsASCII(nosniff_header, "nosniff");

  // CORB should look directly at the Content-Type header if one has been
  // received from the network.  Ignoring |response.head.mime_type| helps avoid
  // breaking legitimate websites (which might happen more often when blocking
  // would be based on the mime type sniffed by MimeSniffingResourceHandler).
  //
  // TODO(nick): What if the mime type is omitted? Should that be treated the
  // same as text/plain? https://crbug.com/795971
  std::string mime_type;
  if (response.head.headers)
    response.head.headers->GetMimeType(&mime_type);
  // Canonicalize the MIME type.  Note that even if it doesn't claim to be a
  // blockable type (i.e., HTML, XML, JSON, or plain text), it may still fail
  // the checks during the SniffForFetchOnlyResource() phase.
  canonical_mime_type_ =
      network::CrossOriginReadBlocking::GetCanonicalMimeType(mime_type);

  // Some types (e.g. ZIP) are protected without any confirmation sniffing.
  if (canonical_mime_type_ == MimeType::kNeverSniffed)
    return kBlock;

  // CORS is currently implemented in the renderer process, so it's useful for
  // CORB to filter failed "cors" mode fetches to avoid leaking the responses to
  // the renderer when possible (e.g., depending on MIME type and sniffing).
  // This will eventually be fixed with OOR-CORS.
  //
  // In the mean time, we can try to filter a few additional failed CORS
  // fetches, treating the Cross-Origin-Resource-Policy (CORP) header as an
  // opt-in to CORB.  CORP headers are enforced elsewhere and normally only
  // apply to "no-cors" mode fetches.  If such a header happens to be on the
  // response during other fetch modes, and if the same-origin and
  // IsValidCorsHeaderSet checks above have failed (and thus the request will
  // fail in the renderer), then we can let CORB filter the response without
  // caring about MIME type or sniffing.
  //
  // To make CrossOriginResourcePolicy::Verify apply to all fetch modes in this
  // case and not just "no-cors", we pass kNoCors as a hard-coded value.  This
  // does not affect the usual enforcement of CORP headers.
  //
  // TODO(lukasza): Once OOR-CORS launches (https://crbug.com/736308), this code
  // block will no longer be necessary since all failed CORS requests will be
  // blocked before reaching the renderer process (even without CORB's help).
  // Of course this assumes that OOR-CORS will use trustworthy
  // |request_initiator| (i.e. vetted against |request_initiator|site_lock|).
  constexpr mojom::FetchRequestMode kOverreachingFetchMode =
      mojom::FetchRequestMode::kNoCors;
  if (CrossOriginResourcePolicy::kBlock ==
      CrossOriginResourcePolicy::Verify(request, response,
                                        kOverreachingFetchMode,
                                        request_initiator_site_lock_)) {
    // Ignore mime types and/or sniffing and have CORB block all responses with
    // COR*P* header.
    return kBlock;
  }

  // If this is a partial response, sniffing is not possible, so allow the
  // response if it's not a protected mime type.
  std::string range_header;
  response.head.headers->GetNormalizedHeader("content-range", &range_header);
  bool has_range_header = !range_header.empty();
  if (has_range_header) {
    switch (canonical_mime_type_) {
      case MimeType::kOthers:
      case MimeType::kPlain:  // See also https://crbug.com/801709
        return kAllow;
      case MimeType::kHtml:
      case MimeType::kJson:
      case MimeType::kXml:
        return kBlock;
      case MimeType::kInvalidMimeType:
      case MimeType::kNeverSniffed:  // Handled much earlier.
        NOTREACHED();
        return kBlock;
    }
  }

  // Decide whether to block based on the MIME type.
  switch (canonical_mime_type_) {
    case MimeType::kHtml:
    case MimeType::kXml:
    case MimeType::kJson:
    case MimeType::kPlain:
      if (has_nosniff_header)
        return kBlock;
      else
        return kNeedToSniffMore;
      break;

    case MimeType::kOthers:
      // Stylesheets shouldn't be sniffed for JSON parser breakers - see
      // https://crbug.com/809259.
      if (base::LowerCaseEqualsASCII(response.head.mime_type, "text/css"))
        return kAllow;
      else
        return kNeedToSniffMore;
      break;

    case MimeType::kInvalidMimeType:
    case MimeType::kNeverSniffed:  // Handled much earlier.
      NOTREACHED();
      return kBlock;
  }
  NOTREACHED();
  return kBlock;
}

void CrossOriginReadBlocking::ResponseAnalyzer::CreateSniffers() {
  // Create one or more |sniffers_| to confirm that the body is actually the
  // MIME type advertised in the Content-Type header.
  DCHECK_EQ(kNeedToSniffMore, should_block_based_on_headers_);
  DCHECK(sniffers_.empty());

  // When the MIME type is "text/plain", create sniffers for HTML, XML and
  // JSON. If any of these sniffers match, the response will be blocked.
  const bool use_all = canonical_mime_type() == MimeType::kPlain;

  // HTML sniffer.
  if (use_all || canonical_mime_type() == MimeType::kHtml) {
    sniffers_.push_back(std::make_unique<SimpleConfirmationSniffer>(
        &network::CrossOriginReadBlocking::SniffForHTML));
  }

  // XML sniffer.
  if (use_all || canonical_mime_type() == MimeType::kXml) {
    sniffers_.push_back(std::make_unique<SimpleConfirmationSniffer>(
        &network::CrossOriginReadBlocking::SniffForXML));
  }

  // JSON sniffer.
  if (use_all || canonical_mime_type() == MimeType::kJson) {
    sniffers_.push_back(std::make_unique<SimpleConfirmationSniffer>(
        &network::CrossOriginReadBlocking::SniffForJSON));
  }

  // Parser-breaker sniffer.
  //
  // Because these prefixes are an XSSI-defeating mechanism, CORB considers
  // them distinctive enough to be worth blocking no matter the Content-Type
  // header. So this sniffer is created unconditionally.
  //
  // For MimeType::kOthers, this will be the only sniffer that's active.
  sniffers_.push_back(std::make_unique<FetchOnlyResourceSniffer>());
}

void CrossOriginReadBlocking::ResponseAnalyzer::SniffResponseBody(
    base::StringPiece data,
    size_t new_data_offset) {
  DCHECK_EQ(kNeedToSniffMore, should_block_based_on_headers_);
  DCHECK(!sniffers_.empty());
  DCHECK(!found_blockable_content_);

  DCHECK_LE(bytes_read_for_sniffing_, static_cast<int>(data.size()));
  bytes_read_for_sniffing_ = static_cast<int>(data.size());

  DCHECK_LE(data.size(), static_cast<size_t>(net::kMaxBytesToSniff));
  DCHECK_LE(new_data_offset, data.size());
  bool has_new_data = (new_data_offset < data.size());

  for (size_t i = 0; i < sniffers_.size();) {
    if (has_new_data)
      sniffers_[i]->OnDataAvailable(data, new_data_offset);

    if (sniffers_[i]->WantsMoreData()) {
      i++;
      continue;
    }

    if (sniffers_[i]->IsConfirmedContentType()) {
      if (sniffers_[i]->IsParserBreakerSniffer())
        found_parser_breaker_ = true;

      found_blockable_content_ = true;
      sniffers_.clear();
      break;
    } else {
      // This response is CORB-exempt as far as this sniffer is concerned;
      // remove it from the list.
      sniffers_.erase(sniffers_.begin() + i);
    }
  }
}

bool CrossOriginReadBlocking::ResponseAnalyzer::ShouldAllow() const {
  switch (should_block_based_on_headers_) {
    case kAllow:
      return true;
    case kNeedToSniffMore:
      return sniffers_.empty() && !found_blockable_content_;
    case kBlock:
      return false;
  }
}

bool CrossOriginReadBlocking::ResponseAnalyzer::ShouldBlock() const {
  switch (should_block_based_on_headers_) {
    case kAllow:
      return false;
    case kNeedToSniffMore:
      return sniffers_.empty() && found_blockable_content_;
    case kBlock:
      return true;
  }
}

bool CrossOriginReadBlocking::ResponseAnalyzer::ShouldReportBlockedResponse()
    const {
  if (!ShouldBlock())
    return false;

  // Don't bother showing a warning message when blocking responses that are
  // already empty.
  if (content_length() == 0)
    return false;
  if (http_response_code() == 204)
    return false;

  // Don't bother showing a warning message when blocking responses that are
  // associated with error responses (e.g. it is quite common to serve a
  // text/html 404 error page for an <img> tag pointing to a wrong URL).
  if (400 <= http_response_code() && http_response_code() <= 599)
    return false;

  return true;
}

void CrossOriginReadBlocking::ResponseAnalyzer::LogBytesReadForSniffing() {
  if (bytes_read_for_sniffing_ >= 0) {
    UMA_HISTOGRAM_COUNTS_1M("SiteIsolation.XSD.Browser.BytesReadForSniffing",
                            bytes_read_for_sniffing_);
  }
}

void CrossOriginReadBlocking::ResponseAnalyzer::LogAllowedResponse() {
  // Note that if a response is allowed because of hitting EOF or
  // kMaxBytesToSniff, then |sniffers_| are not emptied and consequently
  // ShouldAllow doesn't start returning true.  This means that we can't
  // DCHECK(ShouldAllow()) or DCHECK(sniffers_.empty()) here - the decision to
  // allow the response could have been made in the
  // CrossSiteDocumentResourceHandler layer without CrossOriginReadBlocking
  // realizing that it has hit EOF or kMaxBytesToSniff.

  // Note that the response might be allowed even if ShouldBlock() returns true
  // - for example to allow responses to requests initiated by content scripts.
  // This means that we cannot DCHECK(!ShouldBlock()) here.

  CrossOriginReadBlocking::LogAction(
      needs_sniffing()
          ? network::CrossOriginReadBlocking::Action::kAllowedAfterSniffing
          : network::CrossOriginReadBlocking::Action::kAllowedWithoutSniffing);

  LogBytesReadForSniffing();
}

void CrossOriginReadBlocking::ResponseAnalyzer::LogBlockedResponse() {
  DCHECK(!ShouldAllow());
  DCHECK(ShouldBlock());
  DCHECK(sniffers_.empty());

  CrossOriginReadBlocking::LogAction(
      needs_sniffing()
          ? network::CrossOriginReadBlocking::Action::kBlockedAfterSniffing
          : network::CrossOriginReadBlocking::Action::kBlockedWithoutSniffing);

  UMA_HISTOGRAM_BOOLEAN(
      "SiteIsolation.XSD.Browser.Blocked.ContentLength.WasAvailable",
      content_length() >= 0);
  if (content_length() >= 0) {
    UMA_HISTOGRAM_COUNTS_10000(
        "SiteIsolation.XSD.Browser.Blocked.ContentLength.ValueIfAvailable",
        content_length());
  }

  LogBytesReadForSniffing();
}

// static
void CrossOriginReadBlocking::AddExceptionForPlugin(int process_id) {
  std::set<int>& plugin_proxies = GetPluginProxyingProcesses();
  plugin_proxies.insert(process_id);
}

// static
bool CrossOriginReadBlocking::ShouldAllowForPlugin(int process_id) {
  std::set<int>& plugin_proxies = GetPluginProxyingProcesses();
  return base::ContainsKey(plugin_proxies, process_id);
}

// static
void CrossOriginReadBlocking::RemoveExceptionForPlugin(int process_id) {
  std::set<int>& plugin_proxies = GetPluginProxyingProcesses();
  size_t number_of_elements_removed = plugin_proxies.erase(process_id);
  DCHECK_EQ(1u, number_of_elements_removed);
}

}  // namespace network
