OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/safe_browsing/off_domain_inclusion_detector.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/metrics/histogram.h" | |
10 #include "content/public/browser/resource_request_info.h" | |
11 #include "net/url_request/url_request.h" | |
12 #include "url/gurl.h" | |
13 | |
14 namespace safe_browsing { | |
mattm
2014/09/09 21:20:16
Can you add tests? I found one example of testing
| |
15 | |
16 void OffDomainInclusionDetector::OnResourceRequest( | |
17 const net::URLRequest* request, | |
18 content::ResourceType resource_type) { | |
19 // Only look at actual net requests (e.g., not chrome-extensions://id/foo.js). | |
20 if (!request->url().SchemeIsHTTPOrHTTPS()) | |
21 return; | |
22 | |
23 const content::ResourceRequestInfo* request_info = | |
24 content::ResourceRequestInfo::ForRequest(request); | |
25 | |
26 // Make an explicit decision about every resource type (causing compiler | |
27 // errors should a new resource type be added). | |
28 switch (resource_type) { | |
29 case content::RESOURCE_TYPE_MAIN_FRAME: | |
30 // Analyze inclusions in the main frame, not the main frame itself. | |
31 return; | |
32 case content::RESOURCE_TYPE_SUB_FRAME: | |
33 DCHECK(!request_info->IsMainFrame()); | |
34 // Only analyze top-level frames within the main frame. | |
35 if (!request_info->ParentIsMainFrame()) | |
36 return; | |
37 break; | |
38 case content::RESOURCE_TYPE_STYLESHEET: | |
39 case content::RESOURCE_TYPE_SCRIPT: | |
40 case content::RESOURCE_TYPE_IMAGE: | |
41 case content::RESOURCE_TYPE_FONT_RESOURCE: | |
42 case content::RESOURCE_TYPE_SUB_RESOURCE: | |
43 case content::RESOURCE_TYPE_OBJECT: | |
44 case content::RESOURCE_TYPE_MEDIA: | |
45 case content::RESOURCE_TYPE_XHR: | |
46 // Types above are to be analyzed for off-domain inclusion if they are | |
47 // loaded as part of the main frame. | |
48 if (!request_info->IsMainFrame()) | |
49 return; | |
50 break; | |
51 case content::RESOURCE_TYPE_WORKER: | |
52 case content::RESOURCE_TYPE_SHARED_WORKER: | |
53 case content::RESOURCE_TYPE_PREFETCH: | |
54 case content::RESOURCE_TYPE_FAVICON: | |
55 case content::RESOURCE_TYPE_PING: | |
56 case content::RESOURCE_TYPE_SERVICE_WORKER: | |
57 // Types above are not to be analyzed for off-domain inclusion. | |
58 return; | |
59 case content::RESOURCE_TYPE_LAST_TYPE: | |
60 NOTREACHED(); | |
61 return; | |
62 } | |
63 | |
64 // Record the type of request analyzed to be able to do ratio analysis w.r.t | |
65 // other histograms below. | |
66 UMA_HISTOGRAM_ENUMERATION("SBOffDomainInclusion.RequestAnalyzed", | |
67 resource_type, | |
68 content::RESOURCE_TYPE_LAST_TYPE); | |
69 | |
70 const GURL main_frame_url(request->referrer()); | |
71 if (!main_frame_url.is_valid()) { | |
72 if (main_frame_url.is_empty()) { | |
73 // This can happen in a few scenarios where the referer is dropped (e.g., | |
74 // HTTPS => HTTP requests). Consider adding the original referer to | |
75 // ResourceRequestInfo if that's an issue. | |
mattm
2014/09/09 21:20:16
I also have a todo about looking into keeping thes
gab
2014/11/12 20:49:34
Acknowledged.
| |
76 UMA_HISTOGRAM_ENUMERATION("SBOffDomainInclusion.EmptyMainFrameURL", | |
77 resource_type, | |
78 content::RESOURCE_TYPE_LAST_TYPE); | |
79 } else { | |
80 // There is no reason for the main frame to start loading resources if its | |
81 // own URL is invalid but measure this in the wild to make sure. | |
82 UMA_HISTOGRAM_ENUMERATION("SBOffDomainInclusion.InvalidMainFrameURL", | |
83 resource_type, | |
84 content::RESOURCE_TYPE_LAST_TYPE); | |
85 } | |
86 } else { | |
87 // Cut |main_frame_url| down to its host's second-level domain. | |
mattm
2014/09/09 21:20:16
Should use registry_controlled_domains::GetDomainA
gab
2014/11/12 20:49:34
Oh awesome!!! I was looking for exactly that, I ha
| |
88 std::string second_level_host_domain = main_frame_url.host(); | |
89 | |
90 const char kDomainPartDelimiter = '.'; | |
91 size_t tld_delim = | |
92 second_level_host_domain.find_last_of(kDomainPartDelimiter); | |
93 if (tld_delim != std::string::npos && tld_delim != 0U) { | |
94 size_t sld_delim = second_level_host_domain.find_last_of( | |
95 kDomainPartDelimiter, tld_delim - 1); | |
96 if (sld_delim != std::string::npos) | |
97 second_level_host_domain.erase(0U, sld_delim + 1U); | |
98 } | |
99 | |
100 if (!request->url().DomainIs(second_level_host_domain.c_str())) { | |
101 UMA_HISTOGRAM_ENUMERATION("SBOffDomainInclusion.Detected", | |
102 resource_type, | |
103 content::RESOURCE_TYPE_LAST_TYPE); | |
104 } | |
105 } | |
106 } | |
107 | |
108 } // namespace safe_browsing | |
OLD | NEW |