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 "components/password_manager/content/browser/bad_message.h"
6
7 #include "base/logging.h"
8 #include "base/metrics/histogram_functions.h"
9 #include "base/syslog_logging.h"
10 #include "components/password_manager/core/browser/password_form.h"
11 #include "content/public/browser/child_process_security_policy.h"
12 #include "content/public/browser/render_frame_host.h"
13 #include "content/public/browser/render_process_host.h"
14
15 namespace password_manager {
16 namespace bad_message {
17 namespace {
18
19 // Called when the browser receives a bad IPC message from a renderer process on
20 // the UI thread. Logs the event, records a histogram metric for the |reason|,
21 // and terminates the process for |host|.
ReceivedBadMessage(content::RenderProcessHost * host,BadMessageReason reason)22 void ReceivedBadMessage(content::RenderProcessHost* host,
23 BadMessageReason reason) {
24 LOG(ERROR)
25 << "Terminating renderer for bad PasswordManager IPC message, reason "
26 << static_cast<int>(reason);
27 base::UmaHistogramSparse("Stability.BadMessageTerminated.PasswordManager",
28 static_cast<int>(reason));
29 host->ShutdownForBadMessage(
30 content::RenderProcessHost::CrashReportMode::GENERATE_CRASH_DUMP);
31 }
32
33 } // namespace
34
CheckChildProcessSecurityPolicyForURL(content::RenderFrameHost * frame,const GURL & form_url,BadMessageReason reason)35 bool CheckChildProcessSecurityPolicyForURL(content::RenderFrameHost* frame,
36 const GURL& form_url,
37 BadMessageReason reason) {
38 if (form_url.SchemeIs(url::kAboutScheme) ||
39 form_url.SchemeIs(url::kDataScheme)) {
40 SYSLOG(WARNING) << "Killing renderer: illegal password access from about: "
41 << "or data: URL. Reason: " << static_cast<int>(reason);
42 bad_message::ReceivedBadMessage(frame->GetProcess(), reason);
43 return false;
44 }
45
46 content::ChildProcessSecurityPolicy* policy =
47 content::ChildProcessSecurityPolicy::GetInstance();
48 if (!policy->CanAccessDataForOrigin(frame->GetProcess()->GetID(), form_url)) {
49 SYSLOG(WARNING) << "Killing renderer: illegal password access. Reason: "
50 << static_cast<int>(reason);
51 bad_message::ReceivedBadMessage(frame->GetProcess(), reason);
52 return false;
53 }
54
55 return true;
56 }
57
CheckChildProcessSecurityPolicy(content::RenderFrameHost * frame,const PasswordForm & password_form,BadMessageReason reason)58 bool CheckChildProcessSecurityPolicy(content::RenderFrameHost* frame,
59 const PasswordForm& password_form,
60 BadMessageReason reason) {
61 return CheckChildProcessSecurityPolicyForURL(frame, password_form.url,
62 reason) &&
63 CheckChildProcessSecurityPolicyForURL(
64 frame, GURL(password_form.signon_realm), reason) &&
65 CheckChildProcessSecurityPolicyForURL(
66 frame, password_form.form_data.url, reason);
67 }
68
CheckChildProcessSecurityPolicy(content::RenderFrameHost * frame,const std::vector<PasswordForm> & forms,BadMessageReason reason)69 bool CheckChildProcessSecurityPolicy(content::RenderFrameHost* frame,
70 const std::vector<PasswordForm>& forms,
71 BadMessageReason reason) {
72 for (const auto& form : forms) {
73 if (!bad_message::CheckChildProcessSecurityPolicy(frame, form, reason))
74 return false;
75 }
76 return true;
77 }
78
CheckChildProcessSecurityPolicy(content::RenderFrameHost * frame,const std::vector<autofill::FormData> & forms_data,BadMessageReason reason)79 bool CheckChildProcessSecurityPolicy(
80 content::RenderFrameHost* frame,
81 const std::vector<autofill::FormData>& forms_data,
82 BadMessageReason reason) {
83 for (const auto& form_data : forms_data) {
84 if (!bad_message::CheckChildProcessSecurityPolicyForURL(
85 frame, form_data.url, reason)) {
86 return false;
87 }
88 }
89 return true;
90 }
91
92 } // namespace bad_message
93 } // namespace password_manager
94