Skip to content

Commit

Permalink
Using profile's url loader instead of system. (#27595)
Browse files Browse the repository at this point in the history
Applied upstream patch.
  • Loading branch information
boocmp authored Feb 28, 2025
1 parent 32c4ca7 commit 3d612ab
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc
index dca681a3f79ff33f163957da42def9ddca3d8175..2e9e103e8cea8d9cda259d27649a2c441e4437e4 100644
--- a/content/browser/webauth/authenticator_impl_unittest.cc
+++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -63,6 +63,7 @@
#include "content/browser/webauth/client_data_json.h"
#include "content/browser/webauth/virtual_authenticator.h"
#include "content/browser/webauth/virtual_authenticator_manager_impl.h"
+#include "content/browser/webauth/webauth_request_security_checker.h"
#include "content/public/browser/authenticator_request_client_delegate.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
@@ -616,6 +617,9 @@ class AuthenticatorTestBase : public RenderViewHostTestHarness {
void SetUp() override {
RenderViewHostTestHarness::SetUp();

+ WebAuthRequestSecurityChecker::UseSystemSharedURLLoaderFactoryForTesting() =
+ true;
+
mojo::SetDefaultProcessErrorHandler(base::BindRepeating(
&AuthenticatorTestBase::OnMojoError, base::Unretained(this)));

@@ -641,6 +645,8 @@ class AuthenticatorTestBase : public RenderViewHostTestHarness {

void TearDown() override {
RenderViewHostTestHarness::TearDown();
+ WebAuthRequestSecurityChecker::UseSystemSharedURLLoaderFactoryForTesting() =
+ false;

mojo::SetDefaultProcessErrorHandler(base::NullCallback());

91 changes: 91 additions & 0 deletions patches/content-browser-webauth-webauth_browsertest.cc.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
diff --git a/content/browser/webauth/webauth_browsertest.cc b/content/browser/webauth/webauth_browsertest.cc
index 0ebb28807bfd6b9fc543db8d829700213c3fa581..be781a5818b855df4893d8476f63e25866788b69 100644
--- a/content/browser/webauth/webauth_browsertest.cc
+++ b/content/browser/webauth/webauth_browsertest.cc
@@ -40,6 +40,7 @@
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/webauth/authenticator_environment.h"
#include "content/browser/webauth/authenticator_impl.h"
+#include "content/browser/webauth/webauth_request_security_checker.h"
#include "content/public/browser/authenticator_request_client_delegate.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/navigation_throttle.h"
@@ -179,6 +180,11 @@ constexpr char kRpIdNoEntryMessage[] =
".well-known/webauthn resource of the claimed RP ID was "
"successful, but no listed origin matched the caller.";

+constexpr char kRpIdFetchFailedMessage[] =
+ "SecurityError: The relying party ID is not a registrable domain suffix "
+ "of, nor equal to the current domain. Subsequently, an attempt to fetch "
+ "the .well-known/webauthn resource of the claimed RP ID failed.";
+
constexpr char kMaxLargeBlobMessage[] =
"NotSupportedError: The 'largeBlob' extension's 'write' parameter exceeds "
"the maximum allowed size (2kb)";
@@ -1810,6 +1816,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthCrossDomainTest, Create) {
parameters.rp_id = "foo.com";
test_client()->set_webauthn_origins_response(
"application/json", GetHttpsURL("www.acme.com", "/").spec());
+ WebAuthRequestSecurityChecker::UseSystemSharedURLLoaderFactoryForTesting() =
+ true;
std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
BuildCreateCallWithParameters(parameters))
.ExtractString();
@@ -1817,11 +1825,30 @@ IN_PROC_BROWSER_TEST_F(WebAuthCrossDomainTest, Create) {
EXPECT_EQ(kOkMessage, result);
}

+IN_PROC_BROWSER_TEST_F(WebAuthCrossDomainTest, CreateFetchFailed) {
+ CreateParameters parameters;
+ parameters.rp_id = "foo.com";
+ // Set up the system URL loader factory to respond to requests, but do not
+ // force its use. This will result in the browser context-specific URL
+ // loader factory being used, which will fail to handle the request.
+ test_client()->set_webauthn_origins_response(
+ "application/json", GetHttpsURL("www.acme.com", "/").spec());
+ WebAuthRequestSecurityChecker::UseSystemSharedURLLoaderFactoryForTesting() =
+ false;
+ std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
+ BuildCreateCallWithParameters(parameters))
+ .ExtractString();
+
+ EXPECT_EQ(kRpIdFetchFailedMessage, result);
+}
+
IN_PROC_BROWSER_TEST_F(WebAuthCrossDomainTest, CreateBadContentType) {
CreateParameters parameters;
parameters.rp_id = "foo.com";
test_client()->set_webauthn_origins_response(
"text/plain", GetHttpsURL("www.acme.com", "/").spec());
+ WebAuthRequestSecurityChecker::UseSystemSharedURLLoaderFactoryForTesting() =
+ true;
std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
BuildCreateCallWithParameters(parameters))
.ExtractString();
@@ -1834,6 +1861,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthCrossDomainTest, CreateBadOrigin) {
parameters.rp_id = "foo.com";
test_client()->set_webauthn_origins_response("application/json",
"https://nottherightdomain.com");
+ WebAuthRequestSecurityChecker::UseSystemSharedURLLoaderFactoryForTesting() =
+ true;
std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
BuildCreateCallWithParameters(parameters))
.ExtractString();
@@ -1847,6 +1876,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthCrossDomainTest, Timeout) {
parameters.rp_id = "foo.com";
parameters.timeout = kShortTimeout;
test_client()->sinkhole_webauthn_origins_requests();
+ WebAuthRequestSecurityChecker::UseSystemSharedURLLoaderFactoryForTesting() =
+ true;
std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
BuildCreateCallWithParameters(parameters))
.ExtractString();
@@ -1867,6 +1898,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthCrossDomainTest, Get) {
parameters.rp_id = "foo.com";
test_client()->set_webauthn_origins_response(
"application/json", GetHttpsURL("www.acme.com", "/").spec());
+ WebAuthRequestSecurityChecker::UseSystemSharedURLLoaderFactoryForTesting() =
+ true;
std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
BuildGetCallWithParameters(parameters))
.ExtractString();
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
diff --git a/content/browser/webauth/webauth_request_security_checker.cc b/content/browser/webauth/webauth_request_security_checker.cc
index befcc5fe79e376ad4a24d1762bf151138689d418..7303eaffd9302d94484407359102d77e76c6252c 100644
--- a/content/browser/webauth/webauth_request_security_checker.cc
+++ b/content/browser/webauth/webauth_request_security_checker.cc
@@ -10,8 +10,10 @@
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/bad_message.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_authentication_delegate.h"
#include "content/public/browser/webauthn_security_utils.h"
#include "content/public/common/content_client.h"
@@ -84,7 +86,14 @@ std::unique_ptr<WebAuthRequestSecurityChecker::RemoteValidation>
WebAuthRequestSecurityChecker::RemoteValidation::Create(
const url::Origin& caller_origin,
const std::string& relying_party_id,
+ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
base::OnceCallback<void(blink::mojom::AuthenticatorStatus)> callback) {
+ if (!url_loader_factory) {
+ std::move(callback).Run(
+ blink::mojom::AuthenticatorStatus::BAD_RELYING_PARTY_ID);
+ return nullptr;
+ }
+
// The relying party may allow other origins to use its RP ID based on the
// contents of a .well-known file.
std::string canonicalized_domain_storage;
@@ -112,14 +121,6 @@ WebAuthRequestSecurityChecker::RemoteValidation::Create(
replace_host.SetHostStr(canonicalized_domain);
well_known_url = well_known_url.ReplaceComponents(replace_host);

- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory =
- GetContentClient()->browser()->GetSystemSharedURLLoaderFactory();
- if (!url_loader_factory) {
- std::move(callback).Run(
- blink::mojom::AuthenticatorStatus::BAD_RELYING_PARTY_ID);
- return nullptr;
- }
-
auto network_request = std::make_unique<network::ResourceRequest>();
network_request->url = well_known_url;

@@ -256,8 +257,9 @@ bool WebAuthRequestSecurityChecker::IsSameOriginWithAncestors(
const url::Origin& origin) {
RenderFrameHost* parent = render_frame_host_->GetParentOrOuterDocument();
while (parent) {
- if (!parent->GetLastCommittedOrigin().IsSameOriginWith(origin))
+ if (!parent->GetLastCommittedOrigin().IsSameOriginWith(origin)) {
return false;
+ }
parent = parent->GetParentOrOuterDocument();
}
return true;
@@ -376,8 +378,19 @@ WebAuthRequestSecurityChecker::ValidateDomainAndRelyingPartyID(
return nullptr;
}

+ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory;
+ if (!WebAuthRequestSecurityChecker::
+ UseSystemSharedURLLoaderFactoryForTesting()) {
+ url_loader_factory = render_frame_host_->GetStoragePartition()
+ ->GetURLLoaderFactoryForBrowserProcess();
+ }
+ if (!url_loader_factory) {
+ url_loader_factory =
+ GetContentClient()->browser()->GetSystemSharedURLLoaderFactory();
+ }
+
return RemoteValidation::Create(caller_origin, relying_party_id,
- std::move(callback));
+ url_loader_factory, std::move(callback));
}

blink::mojom::AuthenticatorStatus
@@ -515,4 +528,11 @@ bool WebAuthRequestSecurityChecker::
return true;
}

+// static
+bool& WebAuthRequestSecurityChecker::
+ UseSystemSharedURLLoaderFactoryForTesting() {
+ static bool value = false;
+ return value;
+}
+
} // namespace content
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
diff --git a/content/browser/webauth/webauth_request_security_checker.h b/content/browser/webauth/webauth_request_security_checker.h
index 017f2e28a100b911cf8aa321b2395adf14925420..dedfbda18c9c5209e1d5d2a0eddbf906ecf44f9e 100644
--- a/content/browser/webauth/webauth_request_security_checker.h
+++ b/content/browser/webauth/webauth_request_security_checker.h
@@ -23,7 +23,8 @@ class Value;

namespace network {
class SimpleURLLoader;
-}
+class SharedURLLoaderFactory;
+} // namespace network

namespace content {

@@ -60,6 +61,8 @@ class CONTENT_EXPORT WebAuthRequestSecurityChecker
static std::unique_ptr<RemoteValidation> Create(
const url::Origin& caller_origin,
const std::string& relying_party_id,
+ scoped_refptr<network::SharedURLLoaderFactory>
+ shared_url_loader_factory,
base::OnceCallback<void(blink::mojom::AuthenticatorStatus)> callback);

// ValidateWellKnownJSON implements the core of remote validation. It isn't
@@ -154,6 +157,8 @@ class CONTENT_EXPORT WebAuthRequestSecurityChecker
[[nodiscard]] bool DeduplicateCredentialDescriptorListAndValidateLength(
std::vector<device::PublicKeyCredentialDescriptor>* list);

+ static bool& UseSystemSharedURLLoaderFactoryForTesting();
+
protected:
friend class base::RefCounted<WebAuthRequestSecurityChecker>;
virtual ~WebAuthRequestSecurityChecker();

0 comments on commit 3d612ab

Please sign in to comment.