Index: chrome/browser/safe_browsing/incident_reporting/script_request_detector.cc |
diff --git a/chrome/browser/safe_browsing/incident_reporting/script_request_detector.cc b/chrome/browser/safe_browsing/incident_reporting/script_request_detector.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..572b7cd8aedc94d9e9c84cad58819cbfb0e98178 |
--- /dev/null |
+++ b/chrome/browser/safe_browsing/incident_reporting/script_request_detector.cc |
@@ -0,0 +1,176 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
grt (UTC plus 2)
2015/01/28 14:49:05
here, too
robertshield
2015/01/28 22:20:32
It's 2015 you say, that's just like your opinion m
|
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/safe_browsing/incident_reporting/script_request_detector.h" |
+ |
+#include "base/base64.h" |
+#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/safe_browsing/incident_reporting/script_request_incident.h" |
+#include "chrome/common/safe_browsing/csd.pb.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/render_process_host.h" |
+#include "content/public/browser/resource_request_info.h" |
+#include "crypto/sha2.h" |
+#include "net/url_request/url_request.h" |
+#include "url/gurl.h" |
+ |
+namespace { |
+const char* kBase64Hashes[] = { |
grt (UTC plus 2)
2015/01/28 14:49:04
hex-encode these (and make it "const char* const k
robertshield
2015/01/28 22:20:32
Done.
|
+ "K0XA2nlMZRlNeJiFbOi9lfWaWvRO+Z9PkzU7qFLAAvs=", |
+ "Bc5b2v8oF/nJOGJqORt2VuPv7Ugf466TT9PSlodTRfA=", |
+ "OmU9cS06xDUQ1wG2u/tJ2hLOCf1IRXZkEv/UfGFHPAs=", |
+ "lY5NZazqluUR2frMzLfNs8uPTfD4cqDFhwKt5B89+vI=", |
+ "K49YOOuHXaAUkJWJBNPlicXXerZIUxj+cTpq/fCzbqg=", |
+ "qRhlTdP13wn25/4hDxE1mlO/tKheI7EMPGSU9QibKRU=", |
+ "WiubRYFcS6X1m1R4IXN5hzfbiJfZdtkhgPxUg3fbF38=", |
+ "1auT3DrSQO53ghJc93+RXFZiF7tOarg4Yp0KvtOPUNs=", |
+ "23NQ01hQLvwAyu+daPS1dysA+X34iZZuNSIXNU2yibM=", |
+ "3PELsymYrEAkFglLUDzip3/eX992SilUvEnWZxGSFt8=", |
+ "mCgmeqnJi6vWZOTWiXBnl4Q3kosbpN9PSckKEhX/bpE=", |
+ "MKVlQa9gnSqEOJjwQalPl705IK2UOgs+Q6ThkZCf3yU=", |
+ "e0hybUDBL6z3n3OExSp6mG6Yh7fgZb0SxieJVoc9Nkc=", |
+ "e1dI3gh+jrrpYajsqRRw629wPde3c0ueHAGAOWRqHu4=", |
+ "HYa4Wg4iQay/ezUmiZhGHp3CWWwz47dj7Sn5SSzsk7U=", |
+ "LvME011LWMcvi7jpdwGoeBtO6hbKhtt2BI7GhBAVPOY=", |
+ "7AYWqtyW5Lv5drRMbhx6VcZvFQAux12+gWt0AOYpjk4=", |
+ "ukvOtVIrCsYTh1bSLYBvd1qdfSQE/UHkOhrTz3b1IUs=", |
+ "qqv9jYpDm5mYrQHsxbtAgHhE5OxElF/issLTh+Eh0B8=", |
+ "eGSDgcqPCJLSlTard//L9LlcwKHX+vJubKDF++FJSn4=", |
+ "kR4ruWsSMsN0q/Frr/pAHCVQPy9uJZUJX37EkVZWvTQ=", |
+ "oa9o+NwtUmro0hPNcwX3PrGLUrFp6mQkLHl2gRGdoHE=", |
+ "jjzmL8vqehoxEadS/T9oynvwItlv1yFi5LkFhZPQ6vs=", |
+ "qxP8KGcmsDWTgrpw2i3MqY4L7tjRk4mbU5/4EoMTlX0=", |
+ "6XogyJgENOk2m5s8GSvg9d/Hf06UG4oK9jW677wYeSY=", |
+ "JBVCdk0prk4bK9WK24V36ubEISaDFz5/4fTc6NHuOKw=", |
+ "u0T+dus3T07SmXCeIH8IMOx76TpZgYI+RQFBjeUydGg=", |
+ "WhgIubjDFl9LlmqBT+vB4EQF9eqpNOuqfpfR8dTTnDA=", |
+ "rJPqDdXbpOkvot0aSUvbVIqwky9tSFQ5MPGMiYfyS5c=", |
+ "kFVN58yPbzql+ZC3Ivjm+TOeti1Hl0I811+JHjK5zFk=", |
+ "37Dgg/3RPwut1gidR5EQulnch9No8VzcZPnd8OjV3QI=", |
+ "OqCTjHx/m5oqh2Bt1XNtpMashAdoukOUJB+cXxuHVII=", |
+ "dl+tybYA8Cg3Pr77NSuVrMNUCSsEcpK7Om5ceLSoh1g=", |
+ "7DPxOIXwHB7uygUtm9NPilRrkTYQZPZkvh30paEijpc=", |
+ "daPTU7BXvpKc9fnBMJUQ7pPATkidSqGNQOWiQtfywnc=", |
+ "IWYz/8P64XqhBvKeL8bMkx5iF/HMAi85gO40SoXIme0=", |
+ "m2LGK8mw+b2TGv3t+2igwhX+NOrEiXOecJPhH0p1vgk=", |
+ "ueRmROp34XQ9ks9sIH6/Rv1PToIXqH09GdTa3nV08RM=", |
+ "iy4w+i7hoY62ALnjwsmkrXADcuqoaNyVQ23fQCZY3uY=", |
+}; |
+ |
+Profile* GetProfileForRenderProcessId(int render_process_id) { |
+ // How to get a profile from a RenderProcess id: |
+ // 1) Get the RenderProcessHost |
+ // 2) From 1) Get the BrowserContext |
+ // 3) From 2) Get the Profile. |
+ Profile* profile = nullptr; |
+ content::RenderProcessHost* render_process_host = |
+ content::RenderProcessHost::FromID(render_process_id); |
+ if (render_process_host) { |
+ content::BrowserContext* browser_context = |
+ render_process_host->GetBrowserContext(); |
+ if (browser_context) { |
+ profile = Profile::FromBrowserContext(browser_context); |
+ } |
+ } |
+ |
+ return profile; |
+} |
+ |
+} // namespace |
+ |
+namespace safe_browsing { |
+ |
+ScriptRequestDetector::ScriptRequestDetector( |
+ IncidentReportingService* incident_reporting_service) |
+ : incident_reporting_service_(incident_reporting_service), |
+ weak_ptr_factory_(this) { |
+ InitializeScriptSet(); |
+} |
+ |
+ScriptRequestDetector::~ScriptRequestDetector() { |
+} |
+ |
+void ScriptRequestDetector::OnResourceRequest(const net::URLRequest* request) { |
+ // Only look at actual net requests (e.g., not chrome-extensions://id/foo.js). |
+ if (!request->url().SchemeIsHTTPOrHTTPS()) |
+ return; |
+ |
+ const content::ResourceRequestInfo* request_info = |
+ content::ResourceRequestInfo::ForRequest(request); |
+ const content::ResourceType resource_type = request_info->GetResourceType(); |
grt (UTC plus 2)
2015/01/28 14:49:05
only used once, remove
robertshield
2015/01/28 22:20:32
Done.
|
+ |
+ if (resource_type == content::RESOURCE_TYPE_SCRIPT) { |
grt (UTC plus 2)
2015/01/28 14:49:05
to reduce indentation below, how about:
if (requ
robertshield
2015/01/28 22:20:32
Done.
|
+ VLOG(1) << "Script request: " << request->url().spec(); |
grt (UTC plus 2)
2015/01/28 14:49:05
DVLOG
robertshield
2015/01/28 22:20:32
Done.
|
+ |
+ std::string url(request->url().host() + request->url().path()); |
+ std::string raw_hash; |
grt (UTC plus 2)
2015/01/28 14:49:05
std::string raw_hash(crypto::kSHA256Length, '\0');
robertshield
2015/01/28 22:20:32
Done.
|
+ raw_hash.resize(crypto::kSHA256Length); |
+ crypto::SHA256HashString(url.c_str(), &raw_hash[0], crypto::kSHA256Length); |
+ |
+ if (script_set_.find(raw_hash) != script_set_.end()) { |
grt (UTC plus 2)
2015/01/28 14:49:05
if (script_set_.count(raw_hash)) {
robertshield
2015/01/28 22:20:32
Done.
|
+ VLOG(1) << "Script detector match found."; |
grt (UTC plus 2)
2015/01/28 14:49:05
DVLOG
robertshield
2015/01/28 22:20:32
Done.
|
+ |
+ scoped_ptr<ClientIncidentReport_IncidentData_ScriptRequestIncident> |
+ incident_data( |
+ new ClientIncidentReport_IncidentData_ScriptRequestIncident()); |
+ incident_data->set_script_hash(raw_hash); |
+ // TODO(robertshield): Set the domain of the parent frame: |
+ // incident_data->set_inclusion_domain(<something>); |
+ |
+ // This next bit of work needs a profile, so has to happen on the UI |
+ // thread. |
+ int render_frame_id = 0; |
+ int render_process_id = 0; |
+ content::ResourceRequestInfo::GetRenderFrameForRequest( |
+ request, &render_frame_id, &render_process_id); |
+ |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::UI, FROM_HERE, |
+ base::Bind(&ScriptRequestDetector::ReportIncidentOnUIThread, |
+ weak_ptr_factory_.GetWeakPtr(), render_process_id, |
+ base::Passed(incident_data.Pass()))); |
+ } |
+ } |
+} |
+ |
+void ScriptRequestDetector::AddScriptHashForTesting( |
+ const std::string& raw_hash) { |
+ script_set_.insert(raw_hash); |
+} |
+ |
+bool ScriptRequestDetector::ContainsScriptHashForTesting( |
+ const std::string& raw_hash) { |
+ return script_set_.find(raw_hash) != script_set_.end(); |
+} |
+ |
+bool ScriptRequestDetector::AllowNullProfileForTesting() { |
+ return false; |
+} |
+ |
+void ScriptRequestDetector::InitializeScriptSet() { |
+ // Store a hashed set of decoded string hashes. Probably slower than a linear |
+ // search for this size list, but this is only temporary. |
+ for (int i = 0; i < arraysize(kBase64Hashes); ++i) { |
+ std::string raw_hash; |
grt (UTC plus 2)
2015/01/28 14:49:05
move this out of the loop (as above)
robertshield
2015/01/28 22:20:32
Done.
|
+ if (base::Base64Decode(kBase64Hashes[i], &raw_hash)) |
+ script_set_.insert(raw_hash); |
+ } |
+} |
+ |
+void ScriptRequestDetector::ReportIncidentOnUIThread( |
+ int render_process_id, |
+ scoped_ptr<ClientIncidentReport_IncidentData_ScriptRequestIncident> |
+ incident_data) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ |
+ Profile* profile = GetProfileForRenderProcessId(render_process_id); |
+ if (profile || AllowNullProfileForTesting()) { |
+ AddIncidentCallback incident_callback = |
+ incident_reporting_service_->GetAddIncidentCallback(profile); |
+ incident_callback.Run( |
+ make_scoped_ptr(new ScriptRequestIncident(incident_data.Pass()))); |
+ } |
+} |
+ |
+} // namespace safe_browsing |