OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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/incident_reporting/script_request_detecto
r.h" |
| 6 |
| 7 #include "chrome/browser/profiles/profile.h" |
| 8 #include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" |
| 9 #include "chrome/browser/safe_browsing/incident_reporting/script_request_inciden
t.h" |
| 10 #include "chrome/common/safe_browsing/csd.pb.h" |
| 11 #include "content/public/browser/browser_thread.h" |
| 12 #include "content/public/browser/render_frame_host.h" |
| 13 #include "content/public/browser/render_process_host.h" |
| 14 #include "content/public/browser/resource_request_info.h" |
| 15 #include "content/public/browser/site_instance.h" |
| 16 #include "crypto/sha2.h" |
| 17 #include "net/url_request/url_request.h" |
| 18 #include "url/gurl.h" |
| 19 |
| 20 namespace { |
| 21 |
| 22 const char* const kHashes[] = { |
| 23 "\x2b\x45\xc0\xda\x79\x4c\x65\x19\x4d\x78\x98\x85\x6c\xe8\xbd\x95" |
| 24 "\xf5\x9a\x5a\xf4\x4e\xf9\x9f\x4f\x93\x35\x3b\xa8\x52\xc0\x02\xfb", |
| 25 "\x05\xce\x5b\xda\xff\x28\x17\xf9\xc9\x38\x62\x6a\x39\x1b\x76\x56" |
| 26 "\xe3\xef\xed\x48\x1f\xe3\xae\x93\x4f\xd3\xd2\x96\x87\x53\x45\xf0", |
| 27 "\x3a\x65\x3d\x71\x2d\x3a\xc4\x35\x10\xd7\x01\xb6\xbb\xfb\x49\xda" |
| 28 "\x12\xce\x09\xfd\x48\x45\x76\x64\x12\xff\xd4\x7c\x61\x47\x3c\x0b", |
| 29 "\x95\x8e\x4d\x65\xac\xea\x96\xe5\x11\xd9\xfa\xcc\xcc\xb7\xcd\xb3" |
| 30 "\xcb\x8f\x4d\xf0\xf8\x72\xa0\xc5\x87\x02\xad\xe4\x1f\x3d\xfa\xf2", |
| 31 "\x2b\x8f\x58\x38\xeb\x87\x5d\xa0\x14\x90\x95\x89\x04\xd3\xe5\x89" |
| 32 "\xc5\xd7\x7a\xb6\x48\x53\x18\xfe\x71\x3a\x6a\xfd\xf0\xb3\x6e\xa8", |
| 33 "\xa9\x18\x65\x4d\xd3\xf5\xdf\x09\xf6\xe7\xfe\x21\x0f\x11\x35\x9a" |
| 34 "\x53\xbf\xb4\xa8\x5e\x23\xb1\x0c\x3c\x64\x94\xf5\x08\x9b\x29\x15", |
| 35 "\x5a\x2b\x9b\x45\x81\x5c\x4b\xa5\xf5\x9b\x54\x78\x21\x73\x79\x87" |
| 36 "\x37\xdb\x88\x97\xd9\x76\xd9\x21\x80\xfc\x54\x83\x77\xdb\x17\x7f", |
| 37 "\xd5\xab\x93\xdc\x3a\xd2\x40\xee\x77\x82\x12\x5c\xf7\x7f\x91\x5c" |
| 38 "\x56\x62\x17\xbb\x4e\x6a\xb8\x38\x62\x9d\x0a\xbe\xd3\x8f\x50\xdb", |
| 39 "\xdb\x73\x50\xd3\x58\x50\x2e\xfc\x00\xca\xef\x9d\x68\xf4\xb5\x77" |
| 40 "\x2b\x00\xf9\x7d\xf8\x89\x96\x6e\x35\x22\x17\x35\x4d\xb2\x89\xb3", |
| 41 "\xdc\xf1\x0b\xb3\x29\x98\xac\x40\x24\x16\x09\x4b\x50\x3c\xe2\xa7" |
| 42 "\x7f\xde\x5f\xdf\x76\x4a\x29\x54\xbc\x49\xd6\x67\x11\x92\x16\xdf", |
| 43 "\x98\x28\x26\x7a\xa9\xc9\x8b\xab\xd6\x64\xe4\xd6\x89\x70\x67\x97" |
| 44 "\x84\x37\x92\x8b\x1b\xa4\xdf\x4f\x49\xc9\x0a\x12\x15\xff\x6e\x91", |
| 45 "\x30\xa5\x65\x41\xaf\x60\x9d\x2a\x84\x38\x98\xf0\x41\xa9\x4f\x97" |
| 46 "\xbd\x39\x20\xad\x94\x3a\x0b\x3e\x43\xa4\xe1\x91\x90\x9f\xdf\x25", |
| 47 "\x7b\x48\x72\x6d\x40\xc1\x2f\xac\xf7\x9f\x73\x84\xc5\x2a\x7a\x98" |
| 48 "\x6e\x98\x87\xb7\xe0\x65\xbd\x12\xc6\x27\x89\x56\x87\x3d\x36\x47", |
| 49 "\x7b\x57\x48\xde\x08\x7e\x8e\xba\xe9\x61\xa8\xec\xa9\x14\x70\xeb" |
| 50 "\x6f\x70\x3d\xd7\xb7\x73\x4b\x9e\x1c\x01\x80\x39\x64\x6a\x1e\xee", |
| 51 "\x1d\x86\xb8\x5a\x0e\x22\x41\xac\xbf\x7b\x35\x26\x89\x98\x46\x1e" |
| 52 "\x9d\xc2\x59\x6c\x33\xe3\xb7\x63\xed\x29\xf9\x49\x2c\xec\x93\xb5", |
| 53 "\x2e\xf3\x04\xd3\x5d\x4b\x58\xc7\x2f\x8b\xb8\xe9\x77\x01\xa8\x78" |
| 54 "\x1b\x4e\xea\x16\xca\x86\xdb\x76\x04\x8e\xc6\x84\x10\x15\x3c\xe6", |
| 55 "\xec\x06\x16\xaa\xdc\x96\xe4\xbb\xf9\x76\xb4\x4c\x6e\x1c\x7a\x55" |
| 56 "\xc6\x6f\x15\x00\x2e\xc7\x5d\xbe\x81\x6b\x74\x00\xe6\x29\x8e\x4e", |
| 57 "\xba\x4b\xce\xb5\x52\x2b\x0a\xc6\x13\x87\x56\xd2\x2d\x80\x6f\x77" |
| 58 "\x5a\x9d\x7d\x24\x04\xfd\x41\xe4\x3a\x1a\xd3\xcf\x76\xf5\x21\x4b", |
| 59 "\xaa\xab\xfd\x8d\x8a\x43\x9b\x99\x98\xad\x01\xec\xc5\xbb\x40\x80" |
| 60 "\x78\x44\xe4\xec\x44\x94\x5f\xe2\xb2\xc2\xd3\x87\xe1\x21\xd0\x1f", |
| 61 "\x78\x64\x83\x81\xca\x8f\x08\x92\xd2\x95\x36\xab\x77\xff\xcb\xf4" |
| 62 "\xb9\x5c\xc0\xa1\xd7\xfa\xf2\x6e\x6c\xa0\xc5\xfb\xe1\x49\x4a\x7e", |
| 63 "\x91\x1e\x2b\xb9\x6b\x12\x32\xc3\x74\xab\xf1\x6b\xaf\xfa\x40\x1c" |
| 64 "\x25\x50\x3f\x2f\x6e\x25\x95\x09\x5f\x7e\xc4\x91\x56\x56\xbd\x34", |
| 65 "\xa1\xaf\x68\xf8\xdc\x2d\x52\x6a\xe8\xd2\x13\xcd\x73\x05\xf7\x3e" |
| 66 "\xb1\x8b\x52\xb1\x69\xea\x64\x24\x2c\x79\x76\x81\x11\x9d\xa0\x71", |
| 67 "\x8e\x3c\xe6\x2f\xcb\xea\x7a\x1a\x31\x11\xa7\x52\xfd\x3f\x68\xca" |
| 68 "\x7b\xf0\x22\xd9\x6f\xd7\x21\x62\xe4\xb9\x05\x85\x93\xd0\xea\xfb", |
| 69 "\xab\x13\xfc\x28\x67\x26\xb0\x35\x93\x82\xba\x70\xda\x2d\xcc\xa9" |
| 70 "\x8e\x0b\xee\xd8\xd1\x93\x89\x9b\x53\x9f\xf8\x12\x83\x13\x95\x7d", |
| 71 "\xe9\x7a\x20\xc8\x98\x04\x34\xe9\x36\x9b\x9b\x3c\x19\x2b\xe0\xf5" |
| 72 "\xdf\xc7\x7f\x4e\x94\x1b\x8a\x0a\xf6\x35\xba\xef\xbc\x18\x79\x26", |
| 73 "\x24\x15\x42\x76\x4d\x29\xae\x4e\x1b\x2b\xd5\x8a\xdb\x85\x77\xea" |
| 74 "\xe6\xc4\x21\x26\x83\x17\x3e\x7f\xe1\xf4\xdc\xe8\xd1\xee\x38\xac", |
| 75 "\xbb\x44\xfe\x76\xeb\x37\x4f\x4e\xd2\x99\x70\x9e\x20\x7f\x08\x30" |
| 76 "\xec\x7b\xe9\x3a\x59\x81\x82\x3e\x45\x01\x41\x8d\xe5\x32\x74\x68", |
| 77 "\x5a\x18\x08\xb9\xb8\xc3\x16\x5f\x4b\x96\x6a\x81\x4f\xeb\xc1\xe0" |
| 78 "\x44\x05\xf5\xea\xa9\x34\xeb\xaa\x7e\x97\xd1\xf1\xd4\xd3\x9c\x30", |
| 79 "\xac\x93\xea\x0d\xd5\xdb\xa4\xe9\x2f\xa2\xdd\x1a\x49\x4b\xdb\x54" |
| 80 "\x8a\xb0\x93\x2f\x6d\x48\x54\x39\x30\xf1\x8c\x89\x87\xf2\x4b\x97", |
| 81 "\x90\x55\x4d\xe7\xcc\x8f\x6f\x3a\xa5\xf9\x90\xb7\x22\xf8\xe6\xf9" |
| 82 "\x33\x9e\xb6\x2d\x47\x97\x42\x3c\xd7\x5f\x89\x1e\x32\xb9\xcc\x59", |
| 83 "\xdf\xb0\xe0\x83\xfd\xd1\x3f\x0b\xad\xd6\x08\x9d\x47\x91\x10\xba" |
| 84 "\x59\xdc\x87\xd3\x68\xf1\x5c\xdc\x64\xf9\xdd\xf0\xe8\xd5\xdd\x02", |
| 85 "\x3a\xa0\x93\x8c\x7c\x7f\x9b\x9a\x2a\x87\x60\x6d\xd5\x73\x6d\xa4" |
| 86 "\xc6\xac\x84\x07\x68\xba\x43\x94\x24\x1f\x9c\x5f\x1b\x87\x54\x82", |
| 87 "\x76\x5f\xad\xc9\xb6\x00\xf0\x28\x37\x3e\xbe\xfb\x35\x2b\x95\xac" |
| 88 "\xc3\x54\x09\x2b\x04\x72\x92\xbb\x3a\x6e\x5c\x78\xb4\xa8\x87\x58", |
| 89 "\xec\x33\xf1\x38\x85\xf0\x1c\x1e\xee\xca\x05\x2d\x9b\xd3\x4f\x8a" |
| 90 "\x54\x6b\x91\x36\x10\x64\xf6\x64\xbe\x1d\xf4\xa5\xa1\x22\x8e\x97", |
| 91 "\x75\xa3\xd3\x53\xb0\x57\xbe\x92\x9c\xf5\xf9\xc1\x30\x95\x10\xee" |
| 92 "\x93\xc0\x4e\x48\x9d\x4a\xa1\x8d\x40\xe5\xa2\x42\xd7\xf2\xc2\x77", |
| 93 "\x21\x66\x33\xff\xc3\xfa\xe1\x7a\xa1\x06\xf2\x9e\x2f\xc6\xcc\x93" |
| 94 "\x1e\x62\x17\xf1\xcc\x02\x2f\x39\x80\xee\x34\x4a\x85\xc8\x99\xed", |
| 95 "\x9b\x62\xc6\x2b\xc9\xb0\xf9\xbd\x93\x1a\xfd\xed\xfb\x68\xa0\xc2" |
| 96 "\x15\xfe\x34\xea\xc4\x89\x73\x9e\x70\x93\xe1\x1f\x4a\x75\xbe\x09", |
| 97 "\xb9\xe4\x66\x44\xea\x77\xe1\x74\x3d\x92\xcf\x6c\x20\x7e\xbf\x46" |
| 98 "\xfd\x4f\x4e\x82\x17\xa8\x7d\x3d\x19\xd4\xda\xde\x75\x74\xf1\x13", |
| 99 "\x8b\x2e\x30\xfa\x2e\xe1\xa1\x8e\xb6\x00\xb9\xe3\xc2\xc9\xa4\xad" |
| 100 "\x70\x03\x72\xea\xa8\x68\xdc\x95\x43\x6d\xdf\x40\x26\x58\xde\xe6", |
| 101 }; |
| 102 |
| 103 Profile* GetProfileForRenderProcessId(int render_process_id) { |
| 104 // How to get a profile from a RenderProcess id: |
| 105 // 1) Get the RenderProcessHost |
| 106 // 2) From 1) Get the BrowserContext |
| 107 // 3) From 2) Get the Profile. |
| 108 Profile* profile = nullptr; |
| 109 content::RenderProcessHost* render_process_host = |
| 110 content::RenderProcessHost::FromID(render_process_id); |
| 111 if (render_process_host) { |
| 112 content::BrowserContext* browser_context = |
| 113 render_process_host->GetBrowserContext(); |
| 114 if (browser_context) |
| 115 profile = Profile::FromBrowserContext(browser_context); |
| 116 } |
| 117 return profile; |
| 118 } |
| 119 |
| 120 GURL GetUrlForRenderFrameId(int render_process_id, int render_frame_id) { |
| 121 content::RenderFrameHost* render_frame_host = |
| 122 content::RenderFrameHost::FromID(render_process_id, render_frame_id); |
| 123 if (render_frame_host) |
| 124 return render_frame_host->GetLastCommittedURL(); |
| 125 return GURL(); |
| 126 } |
| 127 |
| 128 } // namespace |
| 129 |
| 130 namespace safe_browsing { |
| 131 |
| 132 ScriptRequestDetector::ScriptRequestDetector( |
| 133 scoped_ptr<IncidentReceiver> incident_receiver) |
| 134 : incident_receiver_(incident_receiver.Pass()), |
| 135 allow_null_profile_for_testing_(false), |
| 136 weak_ptr_factory_(this) { |
| 137 InitializeScriptSet(); |
| 138 } |
| 139 |
| 140 ScriptRequestDetector::~ScriptRequestDetector() { |
| 141 } |
| 142 |
| 143 void ScriptRequestDetector::OnResourceRequest(const net::URLRequest* request) { |
| 144 // Only look at actual net requests (e.g., not chrome-extensions://id/foo.js). |
| 145 if (!request->url().SchemeIsHTTPOrHTTPS()) |
| 146 return; |
| 147 |
| 148 const content::ResourceRequestInfo* request_info = |
| 149 content::ResourceRequestInfo::ForRequest(request); |
| 150 |
| 151 if (request_info->GetResourceType() != content::RESOURCE_TYPE_SCRIPT) |
| 152 return; |
| 153 |
| 154 DVLOG(1) << "Script request: " << request->url().spec(); |
| 155 |
| 156 std::string url(request->url().host() + request->url().path()); |
| 157 std::string script_digest(crypto::kSHA256Length, '\0'); |
| 158 crypto::SHA256HashString(url.c_str(), &script_digest[0], |
| 159 crypto::kSHA256Length); |
| 160 |
| 161 if (script_set_.count(script_digest)) { |
| 162 DVLOG(1) << "Script detector match found."; |
| 163 |
| 164 scoped_ptr<ClientIncidentReport_IncidentData_ScriptRequestIncident> |
| 165 incident_data( |
| 166 new ClientIncidentReport_IncidentData_ScriptRequestIncident()); |
| 167 incident_data->set_script_digest(script_digest); |
| 168 |
| 169 // This next bit of work needs a profile, so has to happen on the UI |
| 170 // thread. |
| 171 int render_process_id = 0; |
| 172 int render_frame_id = 0; |
| 173 content::ResourceRequestInfo::GetRenderFrameForRequest( |
| 174 request, &render_process_id, &render_frame_id); |
| 175 |
| 176 content::BrowserThread::PostTask( |
| 177 content::BrowserThread::UI, FROM_HERE, |
| 178 base::Bind(&ScriptRequestDetector::ReportIncidentOnUIThread, |
| 179 weak_ptr_factory_.GetWeakPtr(), render_process_id, |
| 180 render_frame_id, base::Passed(&incident_data))); |
| 181 } |
| 182 } |
| 183 |
| 184 void ScriptRequestDetector::set_allow_null_profile_for_testing( |
| 185 bool allow_null_profile_for_testing) { |
| 186 allow_null_profile_for_testing_ = allow_null_profile_for_testing; |
| 187 } |
| 188 |
| 189 void ScriptRequestDetector::InitializeScriptSet() { |
| 190 // Store a hashed set of decoded string hashes. Probably slower than a linear |
| 191 // search for this size list, but this is only temporary. |
| 192 for (const char* encoded_hash : kHashes) |
| 193 script_set_.insert(std::string(encoded_hash, crypto::kSHA256Length)); |
| 194 } |
| 195 |
| 196 void ScriptRequestDetector::ReportIncidentOnUIThread( |
| 197 int render_process_id, |
| 198 int render_frame_id, |
| 199 scoped_ptr<ClientIncidentReport_IncidentData_ScriptRequestIncident> |
| 200 incident_data) { |
| 201 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 202 |
| 203 Profile* profile = GetProfileForRenderProcessId(render_process_id); |
| 204 if (profile || allow_null_profile_for_testing_) { |
| 205 // Add the URL obtained from the RenderFrameHost, if available. |
| 206 GURL host_url = GetUrlForRenderFrameId(render_process_id, render_frame_id); |
| 207 if (host_url.is_valid()) |
| 208 incident_data->set_inclusion_origin(host_url.GetOrigin().spec()); |
| 209 |
| 210 incident_receiver_->AddIncidentForProfile( |
| 211 profile, |
| 212 make_scoped_ptr(new ScriptRequestIncident(incident_data.Pass()))); |
| 213 } |
| 214 } |
| 215 |
| 216 } // namespace safe_browsing |
OLD | NEW |