// Copyright 2020 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 "content/browser/renderer_host/cross_origin_opener_policy_status.h"

#include <utility>

#include "base/feature_list.h"
#include "base/time/time.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_frame_host_delegate.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "third_party/blink/public/common/origin_trials/trial_token_validator.h"

namespace content {

namespace {

// This function implements the COOP matching algorithm as detailed in [1].
// Note that COEP is also provided since the COOP enum does not have a
// "same-origin + COEP" value.
// [1] https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
bool CrossOriginOpenerPolicyMatch(
    network::mojom::CrossOriginOpenerPolicyValue initiator_coop,
    const url::Origin& initiator_origin,
    network::mojom::CrossOriginOpenerPolicyValue destination_coop,
    const url::Origin& destination_origin) {
  if (initiator_coop != destination_coop)
    return false;

  if (initiator_coop ==
      network::mojom::CrossOriginOpenerPolicyValue::kUnsafeNone) {
    return true;
  }

  if (!initiator_origin.IsSameOriginWith(destination_origin))
    return false;
  return true;
}

// This function returns whether the BrowsingInstance should change following
// COOP rules defined in:
// https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e#changes-to-navigation
bool ShouldSwapBrowsingInstanceForCrossOriginOpenerPolicy(
    network::mojom::CrossOriginOpenerPolicyValue initiator_coop,
    const url::Origin& initiator_origin,
    bool is_initial_navigation,
    network::mojom::CrossOriginOpenerPolicyValue destination_coop,
    const url::Origin& destination_origin) {
  using network::mojom::CrossOriginOpenerPolicyValue;

  // If policies match there is no reason to switch BrowsingInstances.
  if (CrossOriginOpenerPolicyMatch(initiator_coop, initiator_origin,
                                   destination_coop, destination_origin)) {
    return false;
  }

  // "same-origin-allow-popups" is used to stay in the same BrowsingInstance
  // despite COOP mismatch. This case is defined in the spec [1] as follow.
  // ```
  // If the result of matching currentCOOP, currentOrigin, potentialCOOP, and
  // potentialOrigin is false and one of the following is false:
  //  - doc is the initial about:blank document
  //  - currentCOOP is "same-origin-allow-popups"
  //  - potentialCOOP is "unsafe-none"
  // Then create a new browsing context group.
  // ```
  // [1]
  // https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e#changes-to-navigation
  if (is_initial_navigation &&
      initiator_coop == CrossOriginOpenerPolicyValue::kSameOriginAllowPopups &&
      destination_coop == CrossOriginOpenerPolicyValue::kUnsafeNone) {
    return false;
  }
  return true;
}

}  // namespace

CrossOriginOpenerPolicyStatus::CrossOriginOpenerPolicyStatus(
    FrameTreeNode* frame_tree_node,
    const base::Optional<url::Origin>& initiator_origin)
    : frame_tree_node_(frame_tree_node),
      virtual_browsing_context_group_(frame_tree_node->current_frame_host()
                                          ->virtual_browsing_context_group()),
      is_initial_navigation_(!frame_tree_node_->has_committed_real_load()),
      current_coop_(
          frame_tree_node->current_frame_host()->cross_origin_opener_policy()),
      current_origin_(
          frame_tree_node->current_frame_host()->GetLastCommittedOrigin()),
      current_url_(
          frame_tree_node->current_frame_host()->GetLastCommittedURL()),
      is_navigation_source_(initiator_origin.has_value() &&
                            initiator_origin->IsSameOriginWith(
                                frame_tree_node->current_frame_host()
                                    ->GetLastCommittedOrigin())) {
  // Use the URL of the opener for reporting purposes when doing an initial
  // navigation in a popup.
  // Note: the origin check is there to avoid leaking the URL of an opener that
  // navigated in the meantime.
  if (is_initial_navigation_ && frame_tree_node_->opener() &&
      frame_tree_node_->opener()
              ->current_frame_host()
              ->GetLastCommittedOrigin() == current_origin_) {
    current_url_ =
        frame_tree_node_->opener()->current_frame_host()->GetLastCommittedURL();
  }
}

CrossOriginOpenerPolicyStatus::~CrossOriginOpenerPolicyStatus() = default;

base::Optional<network::mojom::BlockedByResponseReason>
CrossOriginOpenerPolicyStatus::EnforceCOOP(
    network::mojom::URLResponseHead* response_head,
    const url::Origin& response_origin,
    const GURL& response_url,
    const GURL& response_referrer_url) {
  SanitizeCoopHeaders(response_url, response_origin, response_head);
  network::mojom::ParsedHeaders* parsed_headers =
      response_head->parsed_headers.get();

  // Return early if the situation prevents COOP from operating.
  if (!frame_tree_node_->IsMainFrame() || response_url.IsAboutBlank()) {
    return base::nullopt;
  }

  network::CrossOriginOpenerPolicy& response_coop =
      parsed_headers->cross_origin_opener_policy;

  // Popups with a sandboxing flag, inherited from their opener, are not
  // allowed to navigate to a document with a Cross-Origin-Opener-Policy that
  // is not "unsafe-none". This ensures a COOP document does not inherit any
  // property from an opener.
  // https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
  if (response_coop.value !=
          network::mojom::CrossOriginOpenerPolicyValue::kUnsafeNone &&
      (frame_tree_node_->pending_frame_policy().sandbox_flags !=
       network::mojom::WebSandboxFlags::kNone)) {
    return network::mojom::BlockedByResponseReason::
        kCoopSandboxedIFrameCannotNavigateToCoopPage;
  }

  StoragePartition* storage_partition = frame_tree_node_->current_frame_host()
                                            ->GetProcess()
                                            ->GetStoragePartition();
  auto response_reporter = std::make_unique<CrossOriginOpenerPolicyReporter>(
      storage_partition, response_url, response_referrer_url, response_coop);
  CrossOriginOpenerPolicyReporter* previous_reporter =
      use_current_document_coop_reporter_
          ? frame_tree_node_->current_frame_host()->coop_reporter()
          : coop_reporter_.get();

  bool cross_origin_policy_swap =
      ShouldSwapBrowsingInstanceForCrossOriginOpenerPolicy(
          current_coop_.value, current_origin_, is_initial_navigation_,
          response_coop.value, response_origin);

  // Both report only cases (navigation from and to document) use the following
  // result, computing the need of a browsing context group swap based on both
  // documents' report-only values.
  bool report_only_coop_swap =
      ShouldSwapBrowsingInstanceForCrossOriginOpenerPolicy(
          current_coop_.report_only_value, current_origin_,
          is_initial_navigation_, response_coop.report_only_value,
          response_origin);

  bool navigating_to_report_only_coop_swap =
      ShouldSwapBrowsingInstanceForCrossOriginOpenerPolicy(
          current_coop_.value, current_origin_, is_initial_navigation_,
          response_coop.report_only_value, response_origin);

  bool navigating_from_report_only_coop_swap =
      ShouldSwapBrowsingInstanceForCrossOriginOpenerPolicy(
          current_coop_.report_only_value, current_origin_,
          is_initial_navigation_, response_coop.value, response_origin);

  bool has_other_window_in_browsing_context_group =
      frame_tree_node_->current_frame_host()
          ->delegate()
          ->GetActiveTopLevelDocumentsInBrowsingContextGroup(
              frame_tree_node_->current_frame_host())
          .size() > 1;

  if (cross_origin_policy_swap) {
    require_browsing_instance_swap_ = true;

    // If this response's COOP causes a BrowsingInstance swap that severs
    // communication with another page, report this to the previous COOP
    // reporter and/or the COOP reporter of the response if they exist.
    if (has_other_window_in_browsing_context_group) {
      response_reporter->QueueNavigationToCOOPReport(
          current_url_, current_origin_.IsSameOriginWith(response_origin),
          false /* is_report_only */);

      if (previous_reporter) {
        previous_reporter->QueueNavigationAwayFromCOOPReport(
            response_url, is_navigation_source_,
            current_origin_.IsSameOriginWith(response_origin),
            false /* is_report_only */);
      }
    }
  }

  bool virtual_browsing_instance_swap =
      report_only_coop_swap && (navigating_to_report_only_coop_swap ||
                                navigating_from_report_only_coop_swap);
  if (virtual_browsing_instance_swap) {
    // If this response's report-only COOP would cause a BrowsingInstance swap
    // that would sever communication with another page, report this to the
    // previous COOP reporter and/or the COOP reporter of the response if they
    // exist.
    if (has_other_window_in_browsing_context_group) {
      response_reporter->QueueNavigationToCOOPReport(
          current_url_, current_origin_.IsSameOriginWith(response_origin),
          true /* is_report_only */);

      if (previous_reporter) {
        previous_reporter->QueueNavigationAwayFromCOOPReport(
            response_url, is_navigation_source_,
            current_origin_.IsSameOriginWith(response_origin),
            true /* is_report_only */);
      }
    }
  }

  if (require_browsing_instance_swap_ || virtual_browsing_instance_swap) {
    virtual_browsing_context_group_ =
        CrossOriginOpenerPolicyReporter::NextVirtualBrowsingContextGroup();
  }

  // Finally, update the current COOP, origin and reporter to those of the
  // response, now that it has been taken into account.
  current_coop_ = response_coop;
  current_origin_ = response_origin;
  current_url_ = response_url;
  coop_reporter_ = std::move(response_reporter);

  // Once a response has been received, reports will be sent to the reporter of
  // the last response received.
  use_current_document_coop_reporter_ = false;

  // Any subsequent response means this response was a redirect, and the source
  // of the navigation to the subsequent response.
  is_navigation_source_ = true;

  return base::nullopt;
}

std::unique_ptr<CrossOriginOpenerPolicyReporter>
CrossOriginOpenerPolicyStatus::TakeCoopReporter() {
  return std::move(coop_reporter_);
}

void CrossOriginOpenerPolicyStatus::UpdateReporterStoragePartition(
    StoragePartition* storage_partition) {
  if (coop_reporter_)
    coop_reporter_->set_storage_partition(storage_partition);
}

// We blank out the COOP headers in a number of situations.
// - When the headers were not sent over HTTPS.
// - For subframes.
// - When the feature is disabled.
// We also strip the "reporting" parts when the reporting feature is disabled
// for the |response_origin|.
void CrossOriginOpenerPolicyStatus::SanitizeCoopHeaders(
    const GURL& response_url,
    const url::Origin& response_origin,
    network::mojom::URLResponseHead* response_head) {
  network::CrossOriginOpenerPolicy& coop =
      response_head->parsed_headers->cross_origin_opener_policy;
  if (coop == network::CrossOriginOpenerPolicy())
    return;

  if (!base::FeatureList::IsEnabled(
          network::features::kCrossOriginOpenerPolicy) ||
      // https://html.spec.whatwg.org/multipage#the-cross-origin-opener-policy-header
      // ```
      // 1. If reservedEnvironment is a non-secure context, then return
      //    "unsafe-none".
      // ```
      !network::IsOriginPotentiallyTrustworthy(response_origin) ||
      // The COOP header must be ignored outside of the top-level context. It is
      // removed as a defensive measure.
      !frame_tree_node_->IsMainFrame()) {
    coop = network::CrossOriginOpenerPolicy();

    if (!network::IsOriginPotentiallyTrustworthy(response_origin))
      header_ignored_due_to_insecure_context_ = true;
    return;
  }

  // The reporting part can be enabled via either a command-line flag or an
  // origin trial.
  bool reporting_enabled = base::FeatureList::IsEnabled(
      network::features::kCrossOriginOpenerPolicyReporting);

  reporting_enabled |=
      base::FeatureList::IsEnabled(
          network::features::kCrossOriginOpenerPolicyReportingOriginTrial) &&
      blink::TrialTokenValidator().RequestEnablesFeature(
          response_url, response_head->headers.get(),
          "CrossOriginOpenerPolicyReporting", base::Time::Now());

  if (!reporting_enabled) {
    coop.reporting_endpoint = base::nullopt;
    coop.report_only_reporting_endpoint = base::nullopt;
    coop.report_only_value =
        network::mojom::CrossOriginOpenerPolicyValue::kUnsafeNone;
  }
}

}  // namespace content
