// 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 "components/safe_browsing/content/browser/client_side_detection_service.h"

#include <algorithm>
#include <memory>

#include "base/bind.h"
#include "base/containers/contains.h"
#include "base/containers/queue.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/strcat.h"
#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/content/browser/client_side_detection_host.h"
#include "components/safe_browsing/content/browser/client_side_phishing_model.h"
#include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
#include "components/safe_browsing/content/common/safe_browsing.mojom.h"
#include "components/safe_browsing/core/common/features.h"
#include "components/safe_browsing/core/common/proto/client_model.pb.h"
#include "components/safe_browsing/core/common/proto/csd.pb.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/safe_browsing/core/common/safebrowsing_constants.h"
#include "components/safe_browsing/core/common/utils.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "crypto/sha2.h"
#include "google_apis/google_api_keys.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/escape.h"
#include "net/base/ip_address.h"
#include "net/base/load_flags.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "url/gurl.h"

using content::BrowserThread;

namespace safe_browsing {

const int ClientSideDetectionService::kReportsIntervalDays = 1;
const int ClientSideDetectionService::kMaxReportsPerInterval = 3;
const int ClientSideDetectionService::kNegativeCacheIntervalDays = 1;
const int ClientSideDetectionService::kPositiveCacheIntervalMinutes = 30;

const char ClientSideDetectionService::kClientReportPhishingUrl[] =
    "https://sb-ssl.google.com/safebrowsing/clientreport/phishing";

struct ClientSideDetectionService::ClientPhishingReportInfo {
  std::unique_ptr<network::SimpleURLLoader> loader;
  ClientReportPhishingRequestCallback callback;
  GURL phishing_url;
};

ClientSideDetectionService::CacheState::CacheState(bool phish, base::Time time)
    : is_phishing(phish), timestamp(time) {}

ClientSideDetectionService::ClientSideDetectionService(
    std::unique_ptr<Delegate> delegate)
    : delegate_(std::move(delegate)) {
  // delegate and prefs can be null in unit tests.
  if (!delegate_ || !delegate_->GetPrefs()) {
    return;
  }

  url_loader_factory_ = delegate_->GetSafeBrowsingURLLoaderFactory();

  pref_change_registrar_.Init(delegate_->GetPrefs());
  pref_change_registrar_.Add(
      prefs::kSafeBrowsingEnabled,
      base::BindRepeating(&ClientSideDetectionService::OnPrefsUpdated,
                          base::Unretained(this)));
  pref_change_registrar_.Add(
      prefs::kSafeBrowsingEnhanced,
      base::BindRepeating(&ClientSideDetectionService::OnPrefsUpdated,
                          base::Unretained(this)));
  pref_change_registrar_.Add(
      prefs::kSafeBrowsingScoutReportingEnabled,
      base::BindRepeating(&ClientSideDetectionService::OnPrefsUpdated,
                          base::Unretained(this)));
  // Do an initial check of the prefs.
  OnPrefsUpdated();
}

ClientSideDetectionService::~ClientSideDetectionService() {
  weak_factory_.InvalidateWeakPtrs();
}

void ClientSideDetectionService::Shutdown() {
  url_loader_factory_.reset();
}

void ClientSideDetectionService::OnPrefsUpdated() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  bool enabled = IsSafeBrowsingEnabled(*delegate_->GetPrefs());
  bool extended_reporting =
      IsEnhancedProtectionEnabled(*delegate_->GetPrefs()) ||
      IsExtendedReportingEnabled(*delegate_->GetPrefs());
  if (enabled == enabled_ && extended_reporting_ == extended_reporting)
    return;

  enabled_ = enabled;
  extended_reporting_ = extended_reporting;

  if (enabled_) {
    update_model_subscription_ =
        ClientSidePhishingModel::GetInstance()->RegisterCallback(
            base::BindRepeating(
                &ClientSideDetectionService::SendModelToRenderers,
                base::Unretained(this)));
  } else {
    // Invoke pending callbacks with a false verdict.
    for (auto& client_phishing_report : client_phishing_reports_) {
      ClientPhishingReportInfo* info = client_phishing_report.second.get();
      if (!info->callback.is_null())
        std::move(info->callback).Run(info->phishing_url, false);
    }
    client_phishing_reports_.clear();
    cache_.clear();
  }

  SendModelToRenderers();  // always refresh the renderer state
}

void ClientSideDetectionService::SendClientReportPhishingRequest(
    std::unique_ptr<ClientPhishingRequest> verdict,
    ClientReportPhishingRequestCallback callback,
    const std::string& access_token) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::BindOnce(
          &ClientSideDetectionService::StartClientReportPhishingRequest,
          weak_factory_.GetWeakPtr(), std::move(verdict), std::move(callback),
          access_token));
}

bool ClientSideDetectionService::IsPrivateIPAddress(
    const std::string& ip_address) const {
  net::IPAddress address;
  if (!address.AssignFromIPLiteral(ip_address)) {
    // Err on the side of privacy and assume this might be private.
    return true;
  }

  return !address.IsPubliclyRoutable();
}

void ClientSideDetectionService::AddClientSideDetectionHost(
    ClientSideDetectionHost* host) {
  csd_hosts_.push_back(host);
}

void ClientSideDetectionService::RemoveClientSideDetectionHost(
    ClientSideDetectionHost* host) {
  std::vector<ClientSideDetectionHost*>::iterator position =
      std::find(csd_hosts_.begin(), csd_hosts_.end(), host);
  if (position != csd_hosts_.end())
    csd_hosts_.erase(position);
}

void ClientSideDetectionService::OnURLLoaderComplete(
    network::SimpleURLLoader* url_loader,
    std::unique_ptr<std::string> response_body) {
  std::string data;
  if (response_body)
    data = std::move(*response_body.get());
  int response_code = 0;
  if (url_loader->ResponseInfo() && url_loader->ResponseInfo()->headers)
    response_code = url_loader->ResponseInfo()->headers->response_code();

  DCHECK(base::Contains(client_phishing_reports_, url_loader));
  HandlePhishingVerdict(url_loader, url_loader->GetFinalURL(),
                        url_loader->NetError(), response_code, data);
}

void ClientSideDetectionService::SendModelToRenderers() {
  for (ClientSideDetectionHost* host : csd_hosts_) {
    host->SendModelToRenderFrame();
  }
}

void ClientSideDetectionService::StartClientReportPhishingRequest(
    std::unique_ptr<ClientPhishingRequest> request,
    ClientReportPhishingRequestCallback callback,
    const std::string& access_token) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (!enabled_) {
    if (!callback.is_null())
      std::move(callback).Run(GURL(request->url()), false);
    return;
  }

  // Fill in metadata about which model we used.
  *request->mutable_population() = delegate_->GetUserPopulation();

  std::string request_data;
  request->SerializeToString(&request_data);

  net::NetworkTrafficAnnotationTag traffic_annotation =
      net::DefineNetworkTrafficAnnotation(
          "safe_browsing_client_side_phishing_detector", R"(
          semantics {
            sender: "Safe Browsing Client-Side Phishing Detector"
            description:
              "If the client-side phishing detector determines that the "
              "current page contents are similar to phishing pages, it will "
              "send a request to Safe Browsing to ask for a final verdict. If "
              "Safe Browsing agrees the page is dangerous, Chrome will show a "
              "full-page interstitial warning."
            trigger:
              "Whenever the clinet-side detector machine learning model "
              "computes a phishy-ness score above a threshold, after page-load."
            data:
              "Top-level page URL without CGI parameters, boolean and double "
              "features extracted from DOM, such as the number of resources "
              "loaded in the page, if certain likely phishing and social "
              "engineering terms found on the page, etc."
            destination: GOOGLE_OWNED_SERVICE
          }
          policy {
            cookies_allowed: YES
            cookies_store: "Safe browsing cookie store"
            setting:
              "Users can enable or disable this feature by toggling 'Protect "
              "you and your device from dangerous sites' in Chrome settings "
              "under Privacy. This feature is enabled by default."
            chrome_policy {
              SafeBrowsingEnabled {
                policy_options {mode: MANDATORY}
                SafeBrowsingEnabled: false
              }
            }
          })");
  auto resource_request = std::make_unique<network::ResourceRequest>();
  base::UmaHistogramBoolean("SBClientPhishing.RequestWithToken",
                            !access_token.empty());
  if (!access_token.empty()) {
    resource_request->headers.SetHeader(
        net::HttpRequestHeaders::kAuthorization,
        base::StrCat({kAuthHeaderBearer, access_token}));
  }

  resource_request->url = GetClientReportUrl(kClientReportPhishingUrl);
  resource_request->method = "POST";
  resource_request->load_flags = net::LOAD_DISABLE_CACHE;
  auto loader = network::SimpleURLLoader::Create(std::move(resource_request),
                                                 traffic_annotation);
  loader->AttachStringForUpload(request_data, "application/octet-stream");
  loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
      url_loader_factory_.get(),
      base::BindOnce(&ClientSideDetectionService::OnURLLoaderComplete,
                     base::Unretained(this), loader.get()));

  // Remember which callback and URL correspond to the current fetcher object.
  std::unique_ptr<ClientPhishingReportInfo> info(new ClientPhishingReportInfo);
  auto* loader_ptr = loader.get();
  info->loader = std::move(loader);
  info->callback = std::move(callback);
  info->phishing_url = GURL(request->url());
  client_phishing_reports_[loader_ptr] = std::move(info);

  // Record that we made a request
  AddPhishingReport(base::Time::Now());

  // The following is to log this ClientPhishingRequest on any open
  // chrome://safe-browsing pages. If no such page is open, the request is
  // dropped and the |request| object deleted.
  base::PostTask(
      FROM_HERE, {content::BrowserThread::UI},
      base::BindOnce(&WebUIInfoSingleton::AddToClientPhishingRequestsSent,
                     base::Unretained(WebUIInfoSingleton::GetInstance()),
                     std::move(request), access_token));
}

void ClientSideDetectionService::HandlePhishingVerdict(
    network::SimpleURLLoader* source,
    const GURL& url,
    int net_error,
    int response_code,
    const std::string& data) {
  ClientPhishingResponse response;
  std::unique_ptr<ClientPhishingReportInfo> info =
      std::move(client_phishing_reports_[source]);
  client_phishing_reports_.erase(source);

  bool is_phishing = false;
  if (net_error == net::OK && net::HTTP_OK == response_code &&
      response.ParseFromString(data)) {
    // Cache response, possibly flushing an old one.
    cache_[info->phishing_url] =
        base::WrapUnique(new CacheState(response.phishy(), base::Time::Now()));
    is_phishing = response.phishy();
  }

  base::PostTask(
      FROM_HERE, {content::BrowserThread::UI},
      base::BindOnce(&WebUIInfoSingleton::AddToClientPhishingResponsesReceived,
                     base::Unretained(WebUIInfoSingleton::GetInstance()),
                     std::make_unique<ClientPhishingResponse>(response)));

  if (!info->callback.is_null())
    std::move(info->callback).Run(info->phishing_url, is_phishing);
}

bool ClientSideDetectionService::IsInCache(const GURL& url) {
  UpdateCache();

  return cache_.find(url) != cache_.end();
}

bool ClientSideDetectionService::GetValidCachedResult(const GURL& url,
                                                      bool* is_phishing) {
  UpdateCache();

  auto it = cache_.find(url);
  if (it == cache_.end()) {
    return false;
  }

  // We still need to check if the result is valid.
  const CacheState& cache_state = *it->second;
  if (cache_state.is_phishing
          ? cache_state.timestamp >
                base::Time::Now() -
                    base::TimeDelta::FromMinutes(kPositiveCacheIntervalMinutes)
          : cache_state.timestamp >
                base::Time::Now() -
                    base::TimeDelta::FromDays(kNegativeCacheIntervalDays)) {
    *is_phishing = cache_state.is_phishing;
    return true;
  }
  return false;
}

void ClientSideDetectionService::UpdateCache() {
  // Since we limit the number of requests but allow pass-through for cache
  // refreshes, we don't want to remove elements from the cache if they
  // could be used for this purpose even if we will not use the entry to
  // satisfy the request from the cache.
  base::TimeDelta positive_cache_interval =
      std::max(base::TimeDelta::FromMinutes(kPositiveCacheIntervalMinutes),
               base::TimeDelta::FromDays(kReportsIntervalDays));
  base::TimeDelta negative_cache_interval =
      std::max(base::TimeDelta::FromDays(kNegativeCacheIntervalDays),
               base::TimeDelta::FromDays(kReportsIntervalDays));

  // Remove elements from the cache that will no longer be used.
  for (auto it = cache_.begin(); it != cache_.end();) {
    const CacheState& cache_state = *it->second;
    if (cache_state.is_phishing
            ? cache_state.timestamp >
                  base::Time::Now() - positive_cache_interval
            : cache_state.timestamp >
                  base::Time::Now() - negative_cache_interval) {
      ++it;
    } else {
      cache_.erase(it++);
    }
  }
}

bool ClientSideDetectionService::OverPhishingReportLimit() {
  return GetPhishingNumReports() > kMaxReportsPerInterval;
}

int ClientSideDetectionService::GetPhishingNumReports() {
  return phishing_report_times_.size();
}

void ClientSideDetectionService::AddPhishingReport(base::Time timestamp) {
  phishing_report_times_.push_back(timestamp);

  base::Time cutoff =
      base::Time::Now() - base::TimeDelta::FromDays(kReportsIntervalDays);

  // Erase items older than cutoff because we will never care about them again.
  while (!phishing_report_times_.empty() &&
         phishing_report_times_.front() < cutoff) {
    phishing_report_times_.pop_front();
  }

  if (!delegate_ || !delegate_->GetPrefs())
    return;

  base::ListValue time_list;
  for (const base::Time& timestamp : phishing_report_times_)
    time_list.Append(base::Value(timestamp.ToDoubleT()));
  delegate_->GetPrefs()->Set(prefs::kSafeBrowsingCsdPingTimestamps, time_list);
}

void ClientSideDetectionService::LoadPhishingReportTimesFromPrefs() {
  if (!delegate_ || !delegate_->GetPrefs())
    return;

  phishing_report_times_.clear();
  for (const base::Value& timestamp :
       delegate_->GetPrefs()
           ->GetList(prefs::kSafeBrowsingCsdPingTimestamps)
           ->GetList()) {
    phishing_report_times_.push_back(
        base::Time::FromDoubleT(timestamp.GetDouble()));
  }
}

// static
GURL ClientSideDetectionService::GetClientReportUrl(
    const std::string& report_url) {
  GURL url(report_url);
  std::string api_key = google_apis::GetAPIKey();
  if (!api_key.empty())
    url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true));

  return url;
}

const std::string& ClientSideDetectionService::GetModelStr() {
  return ClientSidePhishingModel::GetInstance()->GetModelStr();
}

CSDModelType ClientSideDetectionService::GetModelType() {
  return ClientSidePhishingModel::GetInstance()->GetModelType();
}

base::ReadOnlySharedMemoryRegion
ClientSideDetectionService::GetModelSharedMemoryRegion() {
  return ClientSidePhishingModel::GetInstance()->GetModelSharedMemoryRegion();
}

const base::File& ClientSideDetectionService::GetVisualTfLiteModel() {
  return ClientSidePhishingModel::GetInstance()->GetVisualTfLiteModel();
}

void ClientSideDetectionService::SetURLLoaderFactoryForTesting(
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
  url_loader_factory_ = url_loader_factory;
}

}  // namespace safe_browsing
