File: phishing_classifier_delegate.h

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 (201 lines) | stat: -rw-r--r-- 8,592 bytes parent folder | download | duplicates (3)
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// Copyright 2011 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This class is used by the RenderView to interact with a PhishingClassifier.

#ifndef COMPONENTS_SAFE_BROWSING_CONTENT_RENDERER_PHISHING_CLASSIFIER_PHISHING_CLASSIFIER_DELEGATE_H_
#define COMPONENTS_SAFE_BROWSING_CONTENT_RENDERER_PHISHING_CLASSIFIER_PHISHING_CLASSIFIER_DELEGATE_H_

#include <memory>
#include <string>

#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "components/safe_browsing/content/common/safe_browsing.mojom.h"
#include "components/safe_browsing/content/renderer/phishing_classifier/phishing_classifier.h"
#include "components/safe_browsing/content/renderer/phishing_classifier/scorer.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_thread_observer.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "ui/base/page_transition_types.h"
#include "url/gurl.h"

namespace safe_browsing {
class ClientPhishingRequest;
class PhishingClassifier;
class Scorer;

enum class SBPhishingClassifierEvent {
  kPhishingDetectionRequested = 0,
  kPageTextCaptured = 1,
  // Phishing detection could not start because the page text was not loaded.
  kPageTextNotLoaded = 2,
  // Phishing detection could not start because the url was not specified to be
  // classified.
  kUrlShouldNotBeClassified = 3,
  // Phishing detection could not finish because the class was destructed.
  kDestructedBeforeClassificationDone = 4,
  // Scorer is updated and classifier is ready within timeout.
  kScorerUpdatedWithinRetryTimeout = 5,
  kMaxValue = kScorerUpdatedWithinRetryTimeout,
};

class PhishingClassifierDelegate : public content::RenderFrameObserver,
                                   public mojom::PhishingDetector,
                                   public ScorerStorage::Observer {
 public:
  // The RenderFrame owns us.  This object takes ownership of the classifier.
  // Note that if classifier is null, a default instance of PhishingClassifier
  // will be used.
  static PhishingClassifierDelegate* Create(content::RenderFrame* render_frame,
                                            PhishingClassifier* classifier);

  PhishingClassifierDelegate(const PhishingClassifierDelegate&) = delete;
  PhishingClassifierDelegate& operator=(const PhishingClassifierDelegate&) =
      delete;

  ~PhishingClassifierDelegate() override;

  // Called by the RenderFrame once a page has finished loading.  Updates the
  // last-loaded URL and page text, then starts classification if all other
  // conditions are met (see MaybeStartClassification for details).
  // We ignore preliminary captures, since these happen before the page has
  // finished loading.
  void PageCaptured(scoped_refptr<const base::RefCountedString16> page_text,
                    bool preliminary_capture);

  // RenderFrameObserver implementation, public for testing.

  // Called by the RenderFrame when a page has started loading in the given
  // WebFrame.  Typically, this will cause any pending classification to be
  // cancelled.
  void DidCommitProvisionalLoad(ui::PageTransition transition) override;
  // Called by the RenderFrame when the same-document navigation has been
  // committed. We continue running the current classification.
  void DidFinishSameDocumentNavigation() override;

  bool is_ready();

 private:
  friend class PhishingClassifierDelegateTest;

  PhishingClassifierDelegate(content::RenderFrame* render_frame,
                             PhishingClassifier* classifier);

  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  //
  // LINT.IfChange(CancelClassificationReason)
  enum class CancelClassificationReason {
    kNavigateAway = 0,
    kNavigateWithinPage = 1,
    kPageRecaptured = 2,
    kShutdown = 3,
    kNewPhishingScorerUpdate = 4,
    kScorerCleared = 5,
    kMaxValue = kScorerCleared,  // Always add new values before this one.
  };
  // LINT.ThenChange(//tools/metrics/histograms/metadata/sb_client/enums.xml:SBClientPhishingCancelClassificationReason)

  void PhishingDetectorReceiver(
      mojo::PendingAssociatedReceiver<mojom::PhishingDetector> receiver);

  // Cancels any pending classification and frees the page text.
  void CancelPendingClassification(CancelClassificationReason reason);

  // Records in UMA of a specific event that happens in the phishing classifier.
  void RecordEvent(SBPhishingClassifierEvent event);

  void OnDestruct() override;

  // mojom::PhishingDetector
  // Called by the RenderFrame when it receives a StartPhishingDetection IPC
  // from the browser.  This signals that it is ok to begin classification
  // for the given toplevel URL.  If the URL has been fully loaded into the
  // RenderFrame and a Scorer has been set, this will begin classification,
  // otherwise classification will be deferred until these conditions are met.
  void StartPhishingDetection(
      const GURL& url,
      safe_browsing::mojom::ClientSideDetectionType request_type,
      StartPhishingDetectionCallback callback) override;

  // Called when classification for the current page finishes.
  void ClassificationDone(
      const ClientPhishingRequest& verdict,
      PhishingClassifier::Result phishing_classifier_result);

  // Shared code to begin classification if all conditions are met.
  void MaybeStartClassification();

  void OnRetryTimeout();

  // ScorerStorage::Observer implementation:
  void OnScorerChanged() override;

  // The PhishingClassifier to use for the RenderFrame.  This is created once
  // a scorer is made available via SetPhishingScorer().
  std::unique_ptr<PhishingClassifier> classifier_;

  // The last URL that the browser instructed us to classify,
  // with the ref stripped.
  GURL last_url_received_from_browser_;

  // The last top-level URL that has finished loading in the RenderFrame.
  // This corresponds to the text in classifier_page_text_.
  GURL last_finished_load_url_;

  // The transition type for the last load in the main frame.  We use this
  // to exclude back/forward loads from classification.  Note that this is
  // set in DidCommitProvisionalLoad(); the transition is reset after this
  // call in the RenderFrame, so we need to save off the value.
  ui::PageTransition last_main_frame_transition_;

  // The URL of the last load that we actually started classification on.
  // This is used to suppress phishing classification on subframe navigation
  // and back and forward navigations in history.
  GURL last_url_sent_to_classifier_;

  // The page text that will be analyzed by the phishing classifier.  This is
  // set by OnNavigate and cleared when the classifier finishes.  Note that if
  // there is no Scorer yet when OnNavigate is called, or the browser has not
  // instructed us to classify the page, the page text will be cached until
  // these conditions are met.
  scoped_refptr<const base::RefCountedString16> classifier_page_text_;

  // Set to true if the classifier is currently running.
  bool is_classifying_;

  // Set to true when StartPhishingDetection method is called. It is
  // set to false whenever phishing detection has finished.
  bool is_phishing_detection_running_ = false;

  // Set to true when we want to classify for the page, but classifier was not
  // ready. It is set to false whenever |is_phishing_detection_running_| is set
  // to true, classification is happening, completed, or cancelled.
  bool awaiting_retry_ = false;

  // Trigger request type given by the client side detection host class.
  safe_browsing::mojom::ClientSideDetectionType request_type_;

  // The callback from the most recent call to StartPhishingDetection.
  StartPhishingDetectionCallback callback_;

  mojo::AssociatedReceiver<mojom::PhishingDetector> phishing_detector_receiver_{
      this};

  base::ScopedObservation<ScorerStorage, ScorerStorage::Observer>
      model_change_observation_{this};

  base::WeakPtrFactory<PhishingClassifierDelegate> weak_factory_{this};
};

}  // namespace safe_browsing

#endif  // COMPONENTS_SAFE_BROWSING_CONTENT_RENDERER_PHISHING_CLASSIFIER_PHISHING_CLASSIFIER_DELEGATE_H_