// 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 "extensions/browser/url_loader_factory_manager.h"

#include <algorithm>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/command_line.h"
#include "base/containers/flat_set.h"
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/no_destructor.h"
#include "base/sha1.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_map.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/manifest_handlers/content_scripts_handler.h"
#include "extensions/common/switches.h"
#include "extensions/common/user_script.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"
#include "url/scheme_host_port.h"
#include "url/url_constants.h"

namespace extensions {

namespace {

enum class FactoryUser {
  kContentScript,
  kExtensionProcess,
};

// The allowlist contains HashedExtensionId of extensions discovered via
// Extensions.CrossOriginFetchFromContentScript2 Rappor data.  When the data was
// gathered, these extensions relied on making cross-origin requests from
// content scripts (which requires relaxing CORB).  Going forward, these
// extensions should migrate to making those requests from elsewhere (e.g. from
// a background page, or in the future from extension service workers) at which
// point they can be removed from the allowlist.
//
// Migration plan for extension developers is described at
// https://docs.google.com/document/d/1wOFTUmwM4NsDfjY4K6aXAbIyH7WJwLFPPIb5KAa1YZ8
const char* kHardcodedPartOfCorbAllowlist[] = {
    "0149C10F1124F1ED6ACAD85C45E87A76A9DDC667",
    "072D729E856B1F2C9894AEEC3A5DF65E519D6BEE",
    "16A81AEA09A67B03F7AEA5B957D24A4095E764BE",
    "177508B365CBF1610CC2B53707749D79272F2F0B",
    "1AB9CC404876117F49135E67BAD813F935AAE9BA",
    "260871EABEDE6F2D07D0D9450096093EDAFCBF34",
    "2AA94E2D3F4DA33F0D3BCF5DD48F69B8BDB26F52",
    "2FEFB2792E8FF41073E77C8E9B38C159C5A788A8",
    "3334952C8387B357A41DD8349D39AD9E7C423943",
    "33A4A3614CD4BF90F4F2C7984220A9D4FF24DFEF",
    "360D8A88545D0C21CBDE2B55EA9E4E4285282B4C",
    "3FDD3DB17F3B686F5A05204700ABA13DF20AE957",
    "4FC718F4549B18E68A45A11FC2B593033C7049D2",
    "505F2C1E723731B2C8C9182FEAA73D00525B2048",
    "61E581B10D83C0AEF8366BB64C18C6615884B3D2",
    "62D18583FC239861A9661C922A5F13A57EE7EDD7",
    "6AE81EF3B13B15080A2DDB23A205A24C65CCC10B",
    "6BA5F75FFF75B69507BC4B09B7094926EF93DBD2",
    "71EE66C0F71CD89BEE340F8568A44101D4C3A9A7",
    "7BFE588B209A15260DE12777B4BBB738DE98FE6C",
    "808FA9BB3CD501D7801D1CD6D5A3DBA088FDD46F",
    "82FDBBF79F3517C3946BD89EAAF90C46DFDA4681",
    "88C372CE52E21560C17BFD52556E60D694E12CAC",
    "934B8F5753A3E5A276FC7D0EE5E575B335A0CC76",
    "973E35633030AD27DABEC99609424A61386C7309",
    "99E06C364BBB2D1F82A9D20BC1645BF21E478259",
    "A30E526CF62131BFBFD7CD9B56253A8F3F171777",
    "A3660FA31A0DBF07C9F80D5342FF215DBC962719",
    "AEEDAC793F184240CFB800DA73EE6321E5145102",
    "B4782AE831D849EFCC2AF4BE2012816EDDF8D908",
    "BF5224FB246A6B67EA986EFF77A43F6C1BCA9672",
    "C5BCB9E2E47C3F6FD3F7F83ED982872F77852BA7",
    "CA89BD35059845F2DB4B4398FD339B9F210E9337",
    "CC74B2408753932B5D49C81EC073E3E4CA766EE6",
    "D0537B1BADCE856227CE76E31B3772F6B68F653C",
    "E7036E906DBFB77C46EDDEB003A72C0B5CC9BE7F",
    "EC24668224116D19FF1A5FFAA61238B88773982C",
    "F59AB261280AB3AE9826D9359507838B90B07431",
};

constexpr size_t kHashedExtensionIdLength = base::kSHA1Length * 2;
bool IsValidHashedExtensionId(const std::string& hash) {
  bool correct_chars = std::all_of(hash.begin(), hash.end(), [](char c) {
    return ('A' <= c && c <= 'F') || ('0' <= c && c <= '9');
  });
  bool correct_length = (kHashedExtensionIdLength == hash.length());
  return correct_chars && correct_length;
}

std::vector<std::string> CreateExtensionAllowlist() {
  std::vector<std::string> allowlist;
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kForceEmptyCorbAllowlist)) {
    return allowlist;
  }

  // Make sure kHardcodedPartOfAllowlist will fit, but also leave some room
  // for field trial params.
  allowlist.reserve(base::size(kHardcodedPartOfCorbAllowlist) + 10);

  // Append extensions from the hardcoded allowlist.
  for (const char* hash : kHardcodedPartOfCorbAllowlist) {
    DCHECK(IsValidHashedExtensionId(hash));  // It also validates the length.
    allowlist.push_back(std::string(hash, kHashedExtensionIdLength));
  }

  // Append extensions from the field trial param.
  std::string field_trial_arg = base::GetFieldTrialParamValueByFeature(
      extensions_features::kBypassCorbOnlyForExtensionsAllowlist,
      extensions_features::kBypassCorbAllowlistParamName);
  field_trial_arg = base::ToUpperASCII(field_trial_arg);
  std::vector<std::string> field_trial_allowlist = base::SplitString(
      field_trial_arg, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  base::EraseIf(field_trial_allowlist, [](const std::string& hash) {
    // Filter out invalid data from |field_trial_allowlist|.
    if (IsValidHashedExtensionId(hash))
      return false;  // Don't remove.

    LOG(ERROR) << "Invalid extension hash: " << hash;
    return true;  // Remove.
  });
  std::move(field_trial_allowlist.begin(), field_trial_allowlist.end(),
            std::back_inserter(allowlist));

  return allowlist;
}

// Returns a set of HashedExtensionId of extensions that depend on relaxed CORB
// behavior in their content scripts.
const base::flat_set<std::string>& GetExtensionsAllowlist() {
  DCHECK(base::FeatureList::IsEnabled(
      extensions_features::kBypassCorbOnlyForExtensionsAllowlist));
  static const base::NoDestructor<base::flat_set<std::string>> s_allowlist([] {
    base::flat_set<std::string> result(CreateExtensionAllowlist());
    result.shrink_to_fit();
    return result;
  }());
  return *s_allowlist;
}

bool DoContentScriptsDependOnRelaxedCorb(const Extension& extension) {
  // Content scripts injected by Chrome Apps (e.g. into <webview> tag) need to
  // run with relaxed CORB.
  if (extension.is_platform_app())
    return true;

  // Content scripts in the current version of extensions might depend on
  // relaxed CORB.
  if (extension.manifest_version() <= 2) {
    if (!base::FeatureList::IsEnabled(
            extensions_features::kBypassCorbOnlyForExtensionsAllowlist))
      return true;

    const std::string& hash = extension.hashed_id().value();
    DCHECK(IsValidHashedExtensionId(hash));
    return base::ContainsKey(GetExtensionsAllowlist(), hash);
  }

  // Safe fallback for future extension manifest versions.
  return false;
}

bool DoExtensionPermissionsCoverCorsOrCorbRelatedOrigins(
    const Extension& extension) {
  // TODO(lukasza): https://crbug.com/846346: Return false if the |extension|
  // doesn't need a special URLLoaderFactory based on |extension| permissions.
  // For now we conservatively assume that all extensions need relaxed CORS/CORB
  // treatment.
  return true;
}

bool IsSpecialURLLoaderFactoryRequired(const Extension& extension,
                                       FactoryUser factory_user) {
  switch (factory_user) {
    case FactoryUser::kContentScript:
      return DoContentScriptsDependOnRelaxedCorb(extension) &&
             DoExtensionPermissionsCoverCorsOrCorbRelatedOrigins(extension);
    case FactoryUser::kExtensionProcess:
      return DoExtensionPermissionsCoverCorsOrCorbRelatedOrigins(extension);
  }
}

network::mojom::URLLoaderFactoryPtrInfo CreateURLLoaderFactory(
    content::RenderProcessHost* process,
    network::mojom::NetworkContext* network_context,
    network::mojom::TrustedURLLoaderHeaderClientPtrInfo* header_client,
    const Extension& extension) {
  // Compute relaxed CORB config to be used by |extension|.
  network::mojom::URLLoaderFactoryParamsPtr params =
      network::mojom::URLLoaderFactoryParams::New();
  if (header_client)
    params->header_client = std::move(*header_client);
  params->process_id = process->GetID();
  // TODO(lukasza): https://crbug.com/846346: Use more granular CORB enforcement
  // based on the specific |extension|'s permissions.
  params->is_corb_enabled = false;
  params->request_initiator_site_lock = url::Origin::Create(extension.url());

  // Create the URLLoaderFactory.
  network::mojom::URLLoaderFactoryPtrInfo factory_info;
  network_context->CreateURLLoaderFactory(mojo::MakeRequest(&factory_info),
                                          std::move(params));
  return factory_info;
}

void MarkInitiatorsAsRequiringSeparateURLLoaderFactory(
    content::RenderFrameHost* frame,
    std::vector<url::Origin> request_initiators,
    bool push_to_renderer_now) {
  DCHECK(!request_initiators.empty());
  if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
    frame->MarkInitiatorsAsRequiringSeparateURLLoaderFactory(
        std::move(request_initiators), push_to_renderer_now);
  } else {
    // TODO(lukasza): In non-NetworkService implementation of CORB, make an
    // exception only for specific extensions (e.g. based on process id,
    // similarly to how r585124 does it for plugins).  Doing so will likely
    // interfere with Extensions.CrossOriginFetchFromContentScript2 Rappor
    // metric, so this needs to wait until this metric is not needed anymore.
  }
}

// If |match_about_blank| is true, then traverses parent/opener chain until the
// first non-about-scheme document and returns its url.  Otherwise, simply
// returns |document_url|.
//
// This function approximates ScriptContext::GetEffectiveDocumentURL from the
// renderer side.  Unlike the renderer version of this code (in
// ScriptContext::GetEffectiveDocumentURL) the code below doesn't consider
// whether security origin of |frame| can access |next_candidate|.  This is
// okay, because our only caller (DoesContentScriptMatchNavigatingFrame) expects
// false positives.
GURL GetEffectiveDocumentURL(content::RenderFrameHost* frame,
                             const GURL& document_url,
                             bool match_about_blank) {
  base::flat_set<content::RenderFrameHost*> already_visited_frames;

  // Common scenario. If |match_about_blank| is false (as is the case in most
  // extensions), or if the frame is not an about:-page, just return
  // |document_url| (supposedly the URL of the frame).
  if (!match_about_blank || !document_url.SchemeIs(url::kAboutScheme))
    return document_url;

  // Non-sandboxed about:blank and about:srcdoc pages inherit their security
  // origin from their parent frame/window. So, traverse the frame/window
  // hierarchy to find the closest non-about:-page and return its URL.
  content::RenderFrameHost* found_frame = frame;
  do {
    DCHECK(found_frame);
    already_visited_frames.insert(found_frame);

    // The loop should only execute (and consider the parent chain) if the
    // currently considered frame has about: scheme.
    DCHECK(match_about_blank);
    DCHECK(
        ((found_frame == frame) && document_url.SchemeIs(url::kAboutScheme)) ||
        (found_frame->GetLastCommittedURL().SchemeIs(url::kAboutScheme)));

    // Attempt to find |next_candidate| - either a parent of opener of
    // |found_frame|.
    content::RenderFrameHost* next_candidate = found_frame->GetParent();
    if (!next_candidate) {
      next_candidate =
          content::WebContents::FromRenderFrameHost(found_frame)->GetOpener();
    }
    if (!next_candidate ||
        base::ContainsKey(already_visited_frames, next_candidate)) {
      break;
    }

    found_frame = next_candidate;
  } while (found_frame->GetLastCommittedURL().SchemeIs(url::kAboutScheme));

  if (found_frame == frame)
    return document_url;  // Not committed yet at ReadyToCommitNavigation time.
  return found_frame->GetLastCommittedURL();
}

// If |user_script| will inject JavaScript content script into the target of
// |navigation|, then DoesContentScriptMatchNavigatingFrame returns true.
// Otherwise it may return either true or false.  Note that this function
// ignores CSS content scripts.
//
// This function approximates a subset of checks from
// UserScriptSet::GetInjectionForScript (which runs in the renderer process).
// Unlike the renderer version, the code below doesn't consider ability to
// create an injection host or the results of ScriptInjector::CanExecuteOnFrame.
// Additionally the |effective_url| calculations are also only an approximation.
// This is okay, because we may return either true even if no content scripts
// would be injected (i.e. it is okay to create a special URLLoaderFactory when
// in reality the content script won't be injected and won't need the factory).
bool DoesContentScriptMatchNavigatingFrame(
    const UserScript& user_script,
    content::RenderFrameHost* navigating_frame,
    const GURL& navigation_target) {
  // A special URLLoaderFactory is only needed for Javascript content scripts
  // (and is never needed for CSS-only injections).
  if (user_script.js_scripts().empty())
    return false;

  GURL effective_url = GetEffectiveDocumentURL(
      navigating_frame, navigation_target, user_script.match_about_blank());
  bool is_subframe = navigating_frame->GetParent();
  return user_script.MatchesDocument(effective_url, is_subframe);
}

}  // namespace

// static
bool URLLoaderFactoryManager::DoContentScriptsMatchNavigatingFrame(
    const Extension& extension,
    content::RenderFrameHost* navigating_frame,
    const GURL& navigation_target) {
  const UserScriptList& list =
      ContentScriptsInfo::GetContentScripts(&extension);
  return std::any_of(list.begin(), list.end(),
                     [navigating_frame, navigation_target](
                         const std::unique_ptr<UserScript>& script) {
                       return DoesContentScriptMatchNavigatingFrame(
                           *script, navigating_frame, navigation_target);
                     });
}

// static
void URLLoaderFactoryManager::ReadyToCommitNavigation(
    content::NavigationHandle* navigation) {
  content::RenderFrameHost* frame = navigation->GetRenderFrameHost();
  const GURL& url = navigation->GetURL();

  std::vector<url::Origin> initiators_requiring_separate_factory;
  const ExtensionRegistry* registry =
      ExtensionRegistry::Get(frame->GetProcess()->GetBrowserContext());
  DCHECK(registry);  // ReadyToCommitNavigation shouldn't run during shutdown.
  for (const auto& it : registry->enabled_extensions()) {
    const Extension& extension = *it;
    if (!DoContentScriptsMatchNavigatingFrame(extension, frame, url))
      continue;

    if (!IsSpecialURLLoaderFactoryRequired(extension,
                                           FactoryUser::kContentScript))
      continue;

    initiators_requiring_separate_factory.push_back(
        url::Origin::Create(extension.url()));
  }

  if (!initiators_requiring_separate_factory.empty()) {
    // At ReadyToCommitNavigation time there is no need to trigger an explicit
    // push of URLLoaderFactoryBundle to the renderer - it is sufficient if the
    // factories are pushed slightly later - during the commit.
    constexpr bool kPushToRendererNow = false;

    MarkInitiatorsAsRequiringSeparateURLLoaderFactory(
        frame, std::move(initiators_requiring_separate_factory),
        kPushToRendererNow);
  }
}

// static
void URLLoaderFactoryManager::WillExecuteCode(content::RenderFrameHost* frame,
                                              const HostID& host_id) {
  if (host_id.type() != HostID::EXTENSIONS)
    return;

  const ExtensionRegistry* registry =
      ExtensionRegistry::Get(frame->GetProcess()->GetBrowserContext());
  DCHECK(registry);  // WillExecuteCode shouldn't happen during shutdown.
  const Extension* extension =
      registry->enabled_extensions().GetByID(host_id.id());
  DCHECK(extension);  // Guaranteed by the caller - see the doc comment.

  if (!IsSpecialURLLoaderFactoryRequired(*extension,
                                         FactoryUser::kContentScript))
    return;

  // When WillExecuteCode runs, the frame already received the initial
  // URLLoaderFactoryBundle - therefore we need to request a separate push
  // below.  This doesn't race with the ExtensionMsg_ExecuteCode message,
  // because the URLLoaderFactoryBundle is sent to the renderer over
  // content.mojom.FrameNavigationControl interface which is associated with the
  // legacy IPC pipe (raciness will be introduced if that ever changes).
  constexpr bool kPushToRendererNow = true;

  MarkInitiatorsAsRequiringSeparateURLLoaderFactory(
      frame, {url::Origin::Create(extension->url())}, kPushToRendererNow);
}

// static
network::mojom::URLLoaderFactoryPtrInfo URLLoaderFactoryManager::CreateFactory(
    content::RenderProcessHost* process,
    network::mojom::NetworkContext* network_context,
    network::mojom::TrustedURLLoaderHeaderClientPtrInfo* header_client,
    const url::Origin& initiator_origin) {
  content::BrowserContext* browser_context = process->GetBrowserContext();
  const ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context);
  DCHECK(registry);  // CreateFactory shouldn't happen during shutdown.

  // Opaque origins normally don't inherit security properties of their
  // precursor origins, but here opaque origins (e.g. think data: URIs) created
  // by an extension should inherit CORS/CORB treatment of the extension.
  url::SchemeHostPort precursor_origin =
      initiator_origin.GetTupleOrPrecursorTupleIfOpaque();

  // Don't create a factory for something that is not an extension.
  if (precursor_origin.scheme() != kExtensionScheme)
    return network::mojom::URLLoaderFactoryPtrInfo();

  // Find the |extension| associated with |initiator_origin|.
  const Extension* extension =
      registry->enabled_extensions().GetByID(precursor_origin.host());
  if (!extension) {
    // This may happen if an extension gets disabled between the time
    // RenderFrameHost::MarkInitiatorAsRequiringSeparateURLLoaderFactory is
    // called and the time
    // ContentBrowserClient::CreateURLLoaderFactory is called.
    return network::mojom::URLLoaderFactoryPtrInfo();
  }

  // Figure out if the factory is needed for content scripts VS extension
  // renderer.
  FactoryUser factory_user = FactoryUser::kContentScript;
  ProcessMap* process_map = ProcessMap::Get(browser_context);
  if (process_map->Contains(extension->id(), process->GetID()))
    factory_user = FactoryUser::kExtensionProcess;

  // Create the factory (but only if really needed).
  if (!IsSpecialURLLoaderFactoryRequired(*extension, factory_user))
    return network::mojom::URLLoaderFactoryPtrInfo();
  return CreateURLLoaderFactory(process, network_context, header_client,
                                *extension);
}

}  // namespace extensions
