1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/password_manager/content/browser/bad_message.h"
#include "base/test/metrics/histogram_tester.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/test_renderer_host.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace password_manager::bad_message {
class BadMessageTest : public content::RenderViewHostTestHarness {
public:
BadMessageTest() = default;
~BadMessageTest() override = default;
void SetUp() override {
content::RenderViewHostTestHarness::SetUp();
NavigateAndCommit(GURL("https://example.com"));
}
protected:
content::RenderFrameHost* GetMainFrame() {
return web_contents()->GetPrimaryMainFrame();
}
void ExpectNoHistogramEntries(const base::HistogramTester& histogram_tester) {
histogram_tester.ExpectTotalCount(
"Stability.BadMessageTerminated.PasswordManager", 0);
}
void ExpectHistogramEntry(const base::HistogramTester& histogram_tester,
BadMessageReason reason) {
histogram_tester.ExpectUniqueSample(
"Stability.BadMessageTerminated.PasswordManager",
static_cast<int>(reason), 1);
}
};
// Tests that CheckForIllegalURL() allows legitimate HTTPS URLs to proceed.
TEST_F(BadMessageTest, CheckForIllegalURL_ValidURL) {
base::HistogramTester histogram_tester;
GURL valid_url("https://example.com/login");
bool result =
CheckForIllegalURL(GetMainFrame(), valid_url,
BadMessageReason::CPMD_BAD_ORIGIN_FORM_SUBMITTED);
EXPECT_TRUE(result);
ExpectNoHistogramEntries(histogram_tester);
}
// Tests that CheckForIllegalURL() blocks about: URLs and terminates the
// renderer. About URLs (like about:blank) are dangerous because they bypass
// normal web security constraints and could be exploited for privilege
// escalation attacks.
TEST_F(BadMessageTest, CheckForIllegalURL_AboutURL) {
base::HistogramTester histogram_tester;
GURL about_url("about:blank");
bool result =
CheckForIllegalURL(GetMainFrame(), about_url,
BadMessageReason::CPMD_BAD_ORIGIN_FORM_SUBMITTED);
EXPECT_FALSE(result);
ExpectHistogramEntry(histogram_tester,
BadMessageReason::CPMD_BAD_ORIGIN_FORM_SUBMITTED);
}
// Tests that CheckForIllegalURL() blocks data: URLs and terminates the
// renderer. Data URLs contain embedded content that bypasses origin
// restrictions and could be used to inject malicious content for password theft
// attacks.
TEST_F(BadMessageTest, CheckForIllegalURL_DataURL) {
base::HistogramTester histogram_tester;
GURL data_url("data:text/html,<html></html>");
bool result = CheckForIllegalURL(
GetMainFrame(), data_url,
BadMessageReason::CPMD_BAD_ORIGIN_PASSWORD_NO_LONGER_GENERATED);
EXPECT_FALSE(result);
ExpectHistogramEntry(
histogram_tester,
BadMessageReason::CPMD_BAD_ORIGIN_PASSWORD_NO_LONGER_GENERATED);
}
// Tests that CheckChildProcessSecurityPolicyForURL() allows URLs when the
// renderer process has proper permissions.
TEST_F(BadMessageTest, CheckChildProcessSecurityPolicyForURL_ValidURL) {
base::HistogramTester histogram_tester;
GURL valid_url("https://example.com/login");
content::ChildProcessSecurityPolicy::GetInstance()->GrantRequestOrigin(
GetMainFrame()->GetProcess()->GetDeprecatedID(),
url::Origin::Create(valid_url));
bool result = CheckChildProcessSecurityPolicyForURL(
GetMainFrame(), valid_url,
BadMessageReason::CPMD_BAD_ORIGIN_FORM_SUBMITTED);
EXPECT_TRUE(result);
ExpectNoHistogramEntries(histogram_tester);
}
// Tests that CheckChildProcessSecurityPolicyForURL() delegates illegal URL
// detection to CheckForIllegalURL().
TEST_F(BadMessageTest, CheckChildProcessSecurityPolicyForURL_AboutURL) {
base::HistogramTester histogram_tester;
GURL about_url("about:blank");
bool result = CheckChildProcessSecurityPolicyForURL(
GetMainFrame(), about_url,
BadMessageReason::CPMD_BAD_ORIGIN_FORM_SUBMITTED);
EXPECT_FALSE(result);
ExpectHistogramEntry(histogram_tester,
BadMessageReason::CPMD_BAD_ORIGIN_FORM_SUBMITTED);
}
// Tests that CheckFrameNotPrerendering() allows active frames to proceed with
// password manager operations.
TEST_F(BadMessageTest, CheckFrameNotPrerendering_ActiveFrame) {
base::HistogramTester histogram_tester;
bool result = CheckFrameNotPrerendering(GetMainFrame());
EXPECT_TRUE(result);
ExpectNoHistogramEntries(histogram_tester);
}
// Tests that CheckGeneratedPassword() allows non-empty passwords to proceed.
TEST_F(BadMessageTest, CheckGeneratedPassword_ValidPassword) {
base::HistogramTester histogram_tester;
std::u16string valid_password = u"test_password123";
bool result = CheckGeneratedPassword(GetMainFrame(), valid_password);
EXPECT_TRUE(result);
ExpectNoHistogramEntries(histogram_tester);
}
// Tests that CheckGeneratedPassword() blocks empty passwords and terminates
// the renderer.
TEST_F(BadMessageTest, CheckGeneratedPassword_EmptyPassword) {
base::HistogramTester histogram_tester;
std::u16string empty_password;
bool result = CheckGeneratedPassword(GetMainFrame(), empty_password);
EXPECT_FALSE(result);
ExpectHistogramEntry(
histogram_tester,
BadMessageReason::CPMD_BAD_ORIGIN_NO_GENERATED_PASSWORD_TO_EDIT);
}
// Tests that CheckGeneratedPassword() allows whitespace-only passwords.
TEST_F(BadMessageTest, CheckGeneratedPassword_WhitespaceOnlyPassword) {
base::HistogramTester histogram_tester;
std::u16string whitespace_password = u" ";
bool result = CheckGeneratedPassword(GetMainFrame(), whitespace_password);
EXPECT_TRUE(result);
ExpectNoHistogramEntries(histogram_tester);
}
} // namespace password_manager::bad_message
|