File: policy_blocklist_navigation_throttle.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (145 lines) | stat: -rw-r--r-- 5,730 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/policy/content/policy_blocklist_navigation_throttle.h"

#include "base/check_op.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "components/policy/content/policy_blocklist_service.h"
#include "components/policy/content/safe_sites_navigation_throttle.h"
#include "components/policy/core/browser/url_blocklist_manager.h"
#include "components/policy/core/browser/url_blocklist_policy_handler.h"
#include "components/policy/core/common/features.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "url/gurl.h"

using URLBlocklistState = policy::URLBlocklist::URLBlocklistState;
using SafeSitesFilterBehavior = policy::SafeSitesFilterBehavior;

// Passing an Unretained pointer for the safe_sites_navigation_throttle_
// callback is safe because this object owns safe_sites_navigation_throttle_,
// which runs the callback from within the object.
PolicyBlocklistNavigationThrottle::PolicyBlocklistNavigationThrottle(
    content::NavigationThrottleRegistry& registry,
    content::BrowserContext* context)
    : content::NavigationThrottle(registry),
      blocklist_service_(PolicyBlocklistFactory::GetForBrowserContext(context)),
      prefs_(user_prefs::UserPrefs::Get(context)) {
  DCHECK(prefs_);
  auto safe_sites_navigation_throttle =
      std::make_unique<SafeSitesNavigationThrottle>(registry, context);
  if (base::FeatureList::IsEnabled(
          policy::features::kPolicyBlocklistProceedUntilResponse)) {
    safe_sites_navigation_throttle_ =
        std::make_unique<ProceedUntilResponseNavigationThrottle>(
            registry, std::move(safe_sites_navigation_throttle),
            base::BindRepeating(
                &PolicyBlocklistNavigationThrottle::OnDeferredSafeSitesResult,
                base::Unretained(this)));
  } else {
    safe_sites_navigation_throttle->SetDeferredResultCallback(
        base::BindRepeating(
            &PolicyBlocklistNavigationThrottle::OnDeferredSafeSitesResult,
            base::Unretained(this)));
    safe_sites_navigation_throttle_ = std::move(safe_sites_navigation_throttle);
  }
}

PolicyBlocklistNavigationThrottle::~PolicyBlocklistNavigationThrottle() =
    default;

bool PolicyBlocklistNavigationThrottle::IsBlockedViewSourceNavigation() {
  content::NavigationEntry* nav_entry =
      navigation_handle()->GetNavigationEntry();
  if (!nav_entry || !nav_entry->IsViewSourceMode()) {
    return false;
  }

  GURL view_source_url =
      GURL(std::string("view-source:") + navigation_handle()->GetURL().spec());

  return (blocklist_service_->GetURLBlocklistState(view_source_url) ==
          URLBlocklistState::URL_IN_BLOCKLIST);
}

content::NavigationThrottle::ThrottleCheckResult
PolicyBlocklistNavigationThrottle::WillStartOrRedirectRequest(
    bool is_redirect) {
  // Ignore blob scheme because we may use it to deliver navigation responses
  // to the renderer process.
  const GURL& url = navigation_handle()->GetURL();
  if (url.SchemeIs(url::kBlobScheme)) {
    return PROCEED;
  }

  URLBlocklistState blocklist_state =
      blocklist_service_->GetURLBlocklistState(url);
  if (blocklist_state == URLBlocklistState::URL_IN_BLOCKLIST ||
      IsBlockedViewSourceNavigation()) {
    return ThrottleCheckResult(BLOCK_REQUEST,
                               net::ERR_BLOCKED_BY_ADMINISTRATOR);
  }

  if (blocklist_state == URLBlocklistState::URL_IN_ALLOWLIST) {
    return PROCEED;
  }

  return CheckSafeSitesFilter(url, is_redirect);
}

// SafeSitesNavigationThrottle is unconditional and does not check PrefService
// because it is used outside //chrome. Therefore, the policy must be checked
// here to determine whether to use SafeSitesNavigationThrottle.
content::NavigationThrottle::ThrottleCheckResult
PolicyBlocklistNavigationThrottle::CheckSafeSitesFilter(const GURL& url,
                                                        bool is_redirect) {
  SafeSitesFilterBehavior filter_behavior =
      static_cast<SafeSitesFilterBehavior>(
          prefs_->GetInteger(policy::policy_prefs::kSafeSitesFilterBehavior));
  if (filter_behavior == SafeSitesFilterBehavior::kSafeSitesFilterDisabled) {
    return PROCEED;
  }

  CHECK_EQ(filter_behavior, SafeSitesFilterBehavior::kSafeSitesFilterEnabled);
  return is_redirect ? safe_sites_navigation_throttle_->WillRedirectRequest()
                     : safe_sites_navigation_throttle_->WillStartRequest();
}

content::NavigationThrottle::ThrottleCheckResult
PolicyBlocklistNavigationThrottle::WillStartRequest() {
  return WillStartOrRedirectRequest(/*is_redirect=*/false);
}

content::NavigationThrottle::ThrottleCheckResult
PolicyBlocklistNavigationThrottle::WillRedirectRequest() {
  return WillStartOrRedirectRequest(/*is_redirect=*/true);
}

content::NavigationThrottle::ThrottleCheckResult
PolicyBlocklistNavigationThrottle::WillProcessResponse() {
  ThrottleCheckResult result =
      safe_sites_navigation_throttle_->WillProcessResponse();
  return result;
}

const char* PolicyBlocklistNavigationThrottle::GetNameForLogging() {
  return "PolicyBlocklistNavigationThrottle";
}

void PolicyBlocklistNavigationThrottle::OnDeferredSafeSitesResult(
    bool proceed,
    std::optional<ThrottleCheckResult> result) {
  if (proceed) {
    Resume();
  } else {
    CHECK(result.has_value());
    CancelDeferredNavigation(*result);
  }
}