Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: chrome/browser/safe_browsing/client_side_detection_service.cc

Issue 6398001: Run pre-classification checks in the browser before starting client-side phishing detection. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address Noe's review comments Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/safe_browsing/client_side_detection_service.h" 5 #include "chrome/browser/safe_browsing/client_side_detection_service.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/file_path.h" 8 #include "base/file_path.h"
9 #include "base/file_util_proxy.h" 9 #include "base/file_util_proxy.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/platform_file.h" 13 #include "base/platform_file.h"
14 #include "base/scoped_ptr.h" 14 #include "base/scoped_ptr.h"
15 #include "base/stl_util-inl.h" 15 #include "base/stl_util-inl.h"
16 #include "base/task.h" 16 #include "base/task.h"
17 #include "base/time.h" 17 #include "base/time.h"
18 #include "chrome/browser/browser_thread.h" 18 #include "chrome/browser/browser_thread.h"
19 #include "chrome/browser/renderer_host/render_view_host.h"
19 #include "chrome/browser/safe_browsing/csd.pb.h" 20 #include "chrome/browser/safe_browsing/csd.pb.h"
21 #include "chrome/browser/tab_contents/provisional_load_details.h"
22 #include "chrome/browser/tab_contents/tab_contents.h"
20 #include "chrome/common/net/http_return.h" 23 #include "chrome/common/net/http_return.h"
21 #include "chrome/common/net/url_fetcher.h" 24 #include "chrome/common/net/url_fetcher.h"
22 #include "chrome/common/net/url_request_context_getter.h" 25 #include "chrome/common/net/url_request_context_getter.h"
26 #include "chrome/common/notification_service.h"
27 #include "chrome/common/notification_type.h"
28 #include "chrome/common/render_messages.h"
23 #include "googleurl/src/gurl.h" 29 #include "googleurl/src/gurl.h"
24 #include "net/base/load_flags.h" 30 #include "net/base/load_flags.h"
25 #include "net/url_request/url_request_status.h" 31 #include "net/url_request/url_request_status.h"
26 32
27 namespace safe_browsing { 33 namespace safe_browsing {
28 34
29 const int ClientSideDetectionService::kMaxReportsPerDay = 3; 35 const int ClientSideDetectionService::kMaxReportsPerDay = 3;
30 36
31 const char ClientSideDetectionService::kClientReportPhishingUrl[] = 37 const char ClientSideDetectionService::kClientReportPhishingUrl[] =
32 "https://sb-ssl.google.com/safebrowsing/clientreport/phishing"; 38 "https://sb-ssl.google.com/safebrowsing/clientreport/phishing";
33 const char ClientSideDetectionService::kClientModelUrl[] = 39 const char ClientSideDetectionService::kClientModelUrl[] =
34 "https://ssl.gstatic.com/safebrowsing/csd/client_model_v0.pb"; 40 "https://ssl.gstatic.com/safebrowsing/csd/client_model_v0.pb";
35 41
36 struct ClientSideDetectionService::ClientReportInfo { 42 struct ClientSideDetectionService::ClientReportInfo {
37 scoped_ptr<ClientReportPhishingRequestCallback> callback; 43 scoped_ptr<ClientReportPhishingRequestCallback> callback;
38 GURL phishing_url; 44 GURL phishing_url;
39 }; 45 };
40 46
47 // ShouldClassifyUrlRequest tracks the pre-classification checks for a
48 // toplevel URL that has started loading into a renderer. When these
49 // checks are complete, the renderer is notified if it should run
50 // client-side phishing classification, then the ShouldClassifyUrlRequest
51 // deletes itself.
52 class ClientSideDetectionService::ShouldClassifyUrlRequest
53 : public NotificationObserver {
54 public:
55 ShouldClassifyUrlRequest(const GURL& url, TabContents* tab_contents)
56 : url_(url),
57 tab_contents_(tab_contents),
58 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
60 registrar_.Add(this,
61 NotificationType::TAB_CONTENTS_DESTROYED,
62 Source<TabContents>(tab_contents));
63 }
64
65 virtual void Observe(NotificationType type,
66 const NotificationSource& source,
67 const NotificationDetails& details) {
68 switch (type.value) {
69 case NotificationType::TAB_CONTENTS_DESTROYED:
70 Cancel();
71 break;
72 default:
73 NOTREACHED();
74 };
75 }
76
77 void Start() {
78 // TODO(bryner): add pre-classification checks here.
79 // For now we just call Finish() asynchronously for consistency,
80 // since the pre-classification checks are asynchronous.
81 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
82 BrowserThread::PostTask(BrowserThread::UI,
83 FROM_HERE,
84 method_factory_.NewRunnableMethod(
85 &ShouldClassifyUrlRequest::Finish));
86 }
87
88 private:
89 // This object always deletes itself, so make the destructor private.
90 virtual ~ShouldClassifyUrlRequest() {}
91
92 void Cancel() {
93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
94 tab_contents_ = NULL;
95 Finish();
96 }
97
98 void Finish() {
99 if (tab_contents_) {
100 RenderViewHost* rvh = tab_contents_->render_view_host();
101 rvh->Send(new ViewMsg_StartPhishingDetection(rvh->routing_id(), url_));
102 }
103 delete this;
104 }
105
106 GURL url_;
107 TabContents* tab_contents_;
108 NotificationRegistrar registrar_;
109 ScopedRunnableMethodFactory<ShouldClassifyUrlRequest> method_factory_;
110
111 DISALLOW_COPY_AND_ASSIGN(ShouldClassifyUrlRequest);
112 };
113
41 ClientSideDetectionService::ClientSideDetectionService( 114 ClientSideDetectionService::ClientSideDetectionService(
42 const FilePath& model_path, 115 const FilePath& model_path,
43 URLRequestContextGetter* request_context_getter) 116 URLRequestContextGetter* request_context_getter)
44 : model_path_(model_path), 117 : model_path_(model_path),
45 model_status_(UNKNOWN_STATUS), 118 model_status_(UNKNOWN_STATUS),
46 model_file_(base::kInvalidPlatformFileValue), 119 model_file_(base::kInvalidPlatformFileValue),
47 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), 120 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
48 ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)), 121 ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)),
49 request_context_getter_(request_context_getter) { 122 request_context_getter_(request_context_getter) {
123 // Register to find out when pages begin loading into a renderer.
124 // When this happens, we'll start our pre-classificaton checks.
125 registrar_.Add(this,
126 NotificationType::FRAME_PROVISIONAL_LOAD_COMMITTED,
127 NotificationService::AllSources());
50 } 128 }
51 129
52 ClientSideDetectionService::~ClientSideDetectionService() { 130 ClientSideDetectionService::~ClientSideDetectionService() {
53 method_factory_.RevokeAll(); 131 method_factory_.RevokeAll();
54 STLDeleteContainerPairPointers(client_phishing_reports_.begin(), 132 STLDeleteContainerPairPointers(client_phishing_reports_.begin(),
55 client_phishing_reports_.end()); 133 client_phishing_reports_.end());
56 client_phishing_reports_.clear(); 134 client_phishing_reports_.clear();
57 STLDeleteElements(&open_callbacks_); 135 STLDeleteElements(&open_callbacks_);
58 CloseModelFile(); 136 CloseModelFile();
59 } 137 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 if (source == model_fetcher_.get()) { 189 if (source == model_fetcher_.get()) {
112 HandleModelResponse(source, url, status, response_code, cookies, data); 190 HandleModelResponse(source, url, status, response_code, cookies, data);
113 } else if (client_phishing_reports_.find(source) != 191 } else if (client_phishing_reports_.find(source) !=
114 client_phishing_reports_.end()) { 192 client_phishing_reports_.end()) {
115 HandlePhishingVerdict(source, url, status, response_code, cookies, data); 193 HandlePhishingVerdict(source, url, status, response_code, cookies, data);
116 } else { 194 } else {
117 NOTREACHED(); 195 NOTREACHED();
118 } 196 }
119 } 197 }
120 198
199 void ClientSideDetectionService::Observe(NotificationType type,
200 const NotificationSource& source,
201 const NotificationDetails& details) {
202 switch (type.value) {
203 case NotificationType::FRAME_PROVISIONAL_LOAD_COMMITTED: {
204 // Check whether the load should trigger a phishing classification.
205 // This is true if the navigation happened in the main frame and was
206 // not an in-page navigation.
207 ProvisionalLoadDetails* load_details =
208 Details<ProvisionalLoadDetails>(details).ptr();
209
210 if (load_details->main_frame() && !load_details->in_page_navigation()) {
211 NavigationController* controller =
212 Source<NavigationController>(source).ptr();
213 ShouldClassifyUrlRequest* request =
214 new ShouldClassifyUrlRequest(load_details->url(),
215 controller->tab_contents());
216 request->Start(); // the request will delete itself on completion
217 }
218 break;
219 }
220 default:
221 NOTREACHED();
222 };
223 }
224
121 void ClientSideDetectionService::SetModelStatus(ModelStatus status) { 225 void ClientSideDetectionService::SetModelStatus(ModelStatus status) {
122 DCHECK_NE(READY_STATUS, model_status_); 226 DCHECK_NE(READY_STATUS, model_status_);
123 model_status_ = status; 227 model_status_ = status;
124 if (READY_STATUS == status || ERROR_STATUS == status) { 228 if (READY_STATUS == status || ERROR_STATUS == status) {
125 for (size_t i = 0; i < open_callbacks_.size(); ++i) { 229 for (size_t i = 0; i < open_callbacks_.size(); ++i) {
126 open_callbacks_[i]->Run(model_file_); 230 open_callbacks_[i]->Run(model_file_);
127 } 231 }
128 STLDeleteElements(&open_callbacks_); 232 STLDeleteElements(&open_callbacks_);
129 } else { 233 } else {
130 NOTREACHED(); 234 NOTREACHED();
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 while (!phishing_report_times_.empty() && 430 while (!phishing_report_times_.empty() &&
327 phishing_report_times_.front() < cutoff) { 431 phishing_report_times_.front() < cutoff) {
328 phishing_report_times_.pop(); 432 phishing_report_times_.pop();
329 } 433 }
330 434
331 // Return the number of elements that are above the cutoff. 435 // Return the number of elements that are above the cutoff.
332 return phishing_report_times_.size(); 436 return phishing_report_times_.size();
333 } 437 }
334 438
335 } // namespace safe_browsing 439 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698