| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "build/build_config.h" |
| #include "chrome/test/payments/payment_request_platform_browsertest_base.h" |
| #include "content/public/browser/render_process_host.h" |
| #include "content/public/test/browser_test.h" |
| #include "content/public/test/service_worker_host_interceptor.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| #include "url/origin.h" |
| |
| namespace payments { |
| namespace { |
| |
| class PaymentHandlerExploitTest : public PaymentRequestPlatformBrowserTestBase, |
| public content::ServiceWorkerHostInterceptor { |
| protected: |
| PaymentHandlerExploitTest() = default; |
| |
| void set_payment_handler_window_url(const GURL& url) { |
| payment_handler_window_url_ = url; |
| } |
| |
| GURL GetTestServerUrl(const std::string& relative_path) { |
| return https_server()->GetURL("a.com", relative_path); |
| } |
| |
| void SmokeTest() { |
| std::string method_name; |
| InstallPaymentApp("a.com", "/payment_handler_sw.js", &method_name); |
| std::string expected = "success"; |
| EXPECT_EQ(expected, |
| content::EvalJs(GetActiveWebContents(), |
| content::JsReplace("launch($1)", method_name))); |
| } |
| |
| void TestThatRendererCannotOpenCrossOriginWindow() { |
| std::string method_name; |
| InstallPaymentApp("a.com", "/payment_handler_sw.js", &method_name); |
| |
| GURL service_worker_scope = GetTestServerUrl("/"); |
| int service_worker_process_id = -1; |
| EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, |
| InterceptServiceWorkerHostWithScope( |
| GetActiveWebContents()->GetBrowserContext(), |
| service_worker_scope, &service_worker_process_id)); |
| |
| content::RenderProcessHostBadMojoMessageWaiter crash_observer( |
| content::RenderProcessHost::FromID(service_worker_process_id)); |
| |
| GURL cross_origin_url("https://127.0.0.1:80"); |
| EXPECT_FALSE(url::IsSameOriginWith(cross_origin_url, service_worker_scope)); |
| set_payment_handler_window_url(cross_origin_url); |
| |
| content::ExecuteScriptAsync(GetActiveWebContents(), |
| content::JsReplace("launch($1)", method_name)); |
| |
| EXPECT_EQ( |
| "Received bad user message: " |
| "Received PaymentRequestEvent#openWindow() request " |
| "for a cross-origin URL.", |
| crash_observer.Wait()); |
| } |
| |
| private: |
| // PaymentRequestPlatformBrowserTestBase: |
| void SetUpOnMainThread() override { |
| PaymentRequestPlatformBrowserTestBase::SetUpOnMainThread(); |
| NavigateTo("a.com", "/payment_handler.html"); |
| } |
| |
| // content::ServiceWorkerHostInterceptor: |
| bool WillOpenPaymentHandlerWindow(GURL* url) override { |
| *url = payment_handler_window_url_; |
| return true; |
| } |
| |
| GURL payment_handler_window_url_; |
| }; |
| |
| // Android browsertests are not able to open a Chrome Custom Tab for the payment |
| // handler window due to an ActivityNotFoundException: "No Activity found to |
| // handle Intent." https://crbug.com/998737 |
| #if BUILDFLAG(IS_ANDROID) |
| #define MAYBE_SmokeTest DISABLED_SmokeTest |
| #else |
| #define MAYBE_SmokeTest SmokeTest |
| #endif // BUILDFLAG(IS_ANDROID) |
| IN_PROC_BROWSER_TEST_F(PaymentHandlerExploitTest, MAYBE_SmokeTest) { |
| SmokeTest(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(PaymentHandlerExploitTest, |
| RendererCannotOpenCrossOriginWindow) { |
| TestThatRendererCannotOpenCrossOriginWindow(); |
| } |
| |
| } // namespace |
| } // namespace payments |