Commit 0ddd2a9b authored by ricea's avatar ricea Committed by Commit Bot

SafeBrowsing test for WebSocket connection from worker

Only WebSocket connections from the main page were tested. WebSocket connections
from Workers should also lead to display of an interstitial.

Modify malware_websocket.html to accept a "type" query parameter indicating
which environment to create the WebSocket in. Make the MalwareWebSocketBlocked
tests be parameterised on the environment type.

Due to a recent change (https://codereview.chromium.org/2960703003), these
changes need to be tested by passing --enable-features=NetworkService to
browser_tests, as opposed to the --enable-network-service argument that was
needed before.

BUG=644744

Review-Url: https://codereview.chromium.org/2971333002
Cr-Commit-Position: refs/heads/master@{#488151}
parent 36debc58
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <map> #include <map>
#include <set> #include <set>
#include <string>
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
...@@ -1481,7 +1482,14 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, StartAndStop) { ...@@ -1481,7 +1482,14 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, StartAndStop) {
EXPECT_FALSE(csd_service->enabled()); EXPECT_FALSE(csd_service->enabled());
} }
IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, MalwareWebSocketBlocked) { // Parameterised fixture to permit running the same test for Window and Worker
// scopes.
class SafeBrowsingServiceWebSocketTest
: public ::testing::WithParamInterface<std::string>,
public SafeBrowsingServiceTest {};
IN_PROC_BROWSER_TEST_P(SafeBrowsingServiceWebSocketTest,
MalwareWebSocketBlocked) {
// This test currently only passes when the network service is enabled. // This test currently only passes when the network service is enabled.
if (!base::FeatureList::IsEnabled(features::kNetworkService)) if (!base::FeatureList::IsEnabled(features::kNetworkService))
return; return;
...@@ -1492,6 +1500,11 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, MalwareWebSocketBlocked) { ...@@ -1492,6 +1500,11 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, MalwareWebSocketBlocked) {
replace_scheme.SetScheme("ws", url::Component(0, strlen("ws"))); replace_scheme.SetScheme("ws", url::Component(0, strlen("ws")));
GURL websocket_url = resolved.ReplaceComponents(replace_scheme); GURL websocket_url = resolved.ReplaceComponents(replace_scheme);
GURL::Replacements add_query;
std::string query = "type=" + GetParam();
add_query.SetQueryStr(query);
GURL main_url_with_query = main_url.ReplaceComponents(add_query);
// Add the WebSocket url as malware. // Add the WebSocket url as malware.
SBFullHashResult uws_full_hash; SBFullHashResult uws_full_hash;
GenUrlFullHashResult(websocket_url, MALWARE, &uws_full_hash); GenUrlFullHashResult(websocket_url, MALWARE, &uws_full_hash);
...@@ -1509,7 +1522,7 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, MalwareWebSocketBlocked) { ...@@ -1509,7 +1522,7 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, MalwareWebSocketBlocked) {
base::Unretained(this))); base::Unretained(this)));
EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(websocket_url))); EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(websocket_url)));
ui_test_utils::NavigateToURL(browser(), main_url); ui_test_utils::NavigateToURL(browser(), main_url_with_query);
// If the interstitial fails to be displayed, the test will hang here. // If the interstitial fails to be displayed, the test will hang here.
load_stop_observer.Wait(); load_stop_observer.Wait();
...@@ -1518,6 +1531,11 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, MalwareWebSocketBlocked) { ...@@ -1518,6 +1531,11 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, MalwareWebSocketBlocked) {
EXPECT_TRUE(got_hit_report()); EXPECT_TRUE(got_hit_report());
} }
INSTANTIATE_TEST_CASE_P(
/* no prefix */,
SafeBrowsingServiceWebSocketTest,
::testing::Values("window", "worker"));
IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, UnknownWebSocketNotBlocked) { IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, UnknownWebSocketNotBlocked) {
GURL main_url = embedded_test_server()->GetURL(kMalwareWebSocketPage); GURL main_url = embedded_test_server()->GetURL(kMalwareWebSocketPage);
...@@ -2243,10 +2261,17 @@ IN_PROC_BROWSER_TEST_F(V4SafeBrowsingServiceTest, CheckBrowseUrl) { ...@@ -2243,10 +2261,17 @@ IN_PROC_BROWSER_TEST_F(V4SafeBrowsingServiceTest, CheckBrowseUrl) {
} }
} }
// Parameterised fixture to permit running the same test for Window and Worker
// scopes.
class V4SafeBrowsingServiceWebSocketTest
: public ::testing::WithParamInterface<std::string>,
public V4SafeBrowsingServiceTest {};
// This is almost identical to // This is almost identical to
// SafeBrowsingServiceTest.MalwareWebSocketBlocked. That test will be deleted // SafeBrowsingServiceWebSocketTest.MalwareWebSocketBlocked. That test will be
// when the old database backend stops being used. // deleted when the old database backend is removed.
IN_PROC_BROWSER_TEST_F(V4SafeBrowsingServiceTest, MalwareWebSocketBlocked) { IN_PROC_BROWSER_TEST_P(V4SafeBrowsingServiceWebSocketTest,
MalwareWebSocketBlocked) {
// This test currently only passes when the network service is enabled. // This test currently only passes when the network service is enabled.
if (!base::FeatureList::IsEnabled(features::kNetworkService)) if (!base::FeatureList::IsEnabled(features::kNetworkService))
return; return;
...@@ -2257,6 +2282,11 @@ IN_PROC_BROWSER_TEST_F(V4SafeBrowsingServiceTest, MalwareWebSocketBlocked) { ...@@ -2257,6 +2282,11 @@ IN_PROC_BROWSER_TEST_F(V4SafeBrowsingServiceTest, MalwareWebSocketBlocked) {
replace_scheme.SetScheme("ws", url::Component(0, strlen("ws"))); replace_scheme.SetScheme("ws", url::Component(0, strlen("ws")));
GURL websocket_url = resolved.ReplaceComponents(replace_scheme); GURL websocket_url = resolved.ReplaceComponents(replace_scheme);
GURL::Replacements add_query;
std::string query = "type=" + GetParam();
add_query.SetQueryStr(query);
GURL main_url_with_query = main_url.ReplaceComponents(add_query);
MarkUrlForMalwareUnexpired(websocket_url); MarkUrlForMalwareUnexpired(websocket_url);
// Brute force method for waiting for the interstitial to be displayed. // Brute force method for waiting for the interstitial to be displayed.
...@@ -2271,7 +2301,7 @@ IN_PROC_BROWSER_TEST_F(V4SafeBrowsingServiceTest, MalwareWebSocketBlocked) { ...@@ -2271,7 +2301,7 @@ IN_PROC_BROWSER_TEST_F(V4SafeBrowsingServiceTest, MalwareWebSocketBlocked) {
base::Unretained(this))); base::Unretained(this)));
EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(websocket_url))); EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(websocket_url)));
ui_test_utils::NavigateToURL(browser(), main_url); ui_test_utils::NavigateToURL(browser(), main_url_with_query);
// If the interstitial fails to be displayed, the test will hang here. // If the interstitial fails to be displayed, the test will hang here.
load_stop_observer.Wait(); load_stop_observer.Wait();
...@@ -2279,10 +2309,15 @@ IN_PROC_BROWSER_TEST_F(V4SafeBrowsingServiceTest, MalwareWebSocketBlocked) { ...@@ -2279,10 +2309,15 @@ IN_PROC_BROWSER_TEST_F(V4SafeBrowsingServiceTest, MalwareWebSocketBlocked) {
EXPECT_TRUE(ShowingInterstitialPage()); EXPECT_TRUE(ShowingInterstitialPage());
EXPECT_TRUE(got_hit_report()); EXPECT_TRUE(got_hit_report());
EXPECT_EQ(websocket_url, hit_report().malicious_url); EXPECT_EQ(websocket_url, hit_report().malicious_url);
EXPECT_EQ(main_url, hit_report().page_url); EXPECT_EQ(main_url_with_query, hit_report().page_url);
EXPECT_TRUE(hit_report().is_subresource); EXPECT_TRUE(hit_report().is_subresource);
} }
// TODO(ricea): Test SharedWorker and ServiceWorker scopes as well.
INSTANTIATE_TEST_CASE_P(/* no prefix */,
V4SafeBrowsingServiceWebSocketTest,
::testing::Values("window", "worker"));
// Identical to SafeBrowsingServiceTest.UnknownWebSocketNotBlocked. Uses the // Identical to SafeBrowsingServiceTest.UnknownWebSocketNotBlocked. Uses the
// V4 database backend. // V4 database backend.
IN_PROC_BROWSER_TEST_F(V4SafeBrowsingServiceTest, UnknownWebSocketNotBlocked) { IN_PROC_BROWSER_TEST_F(V4SafeBrowsingServiceTest, UnknownWebSocketNotBlocked) {
......
<title>Test whether a WebSocket connection triggers a SafeBrowsing interstitial</title> <title>Test whether a WebSocket connection triggers a SafeBrowsing interstitial</title>
<script> <script>
const url = new URL(document.location.href);
const type = url.searchParams.get('type');
// Construct the WebSocket URL from the page URL. The server should not be // Construct the WebSocket URL from the page URL. The server should not be
// configured to accept a WebSocket handshake at this endpoint, or the "not // configured to accept a WebSocket handshake at this endpoint, or the "not
// blocked" test will fail. A 404 error is perfect. // blocked" test will fail. A 404 error is perfect.
const wsUrl = new URL('/safe_browsing/malware-ws', document.location.href); const wsUrl = new URL('/safe_browsing/malware-ws', url);
wsUrl.protocol = 'ws'; wsUrl.protocol = 'ws';
const ws = new WebSocket(wsUrl.href);
// The "not blocked" test looks for this title change to verify that the request function workerTest() {
// has not been blocked. const src = `
ws.onerror = () => { document.title = 'COMPLETED'; }; const ws = new WebSocket('${wsUrl}');
ws.onerror = () => {
postMessage('COMPLETED');
};
`;
const blob = new Blob([src]);
const srcUrl = URL.createObjectURL(blob);
const worker = new Worker(srcUrl);
worker.onmessage = signalComplete;
}
switch (type) {
case 'worker':
workerTest();
break;
default:
windowTest();
break;
}
function windowTest() {
const ws = new WebSocket(wsUrl.href);
ws.onerror = signalComplete;
}
function signalComplete() {
// The "not blocked" test looks for this title change to verify that the
// request has not been blocked.
document.title = 'COMPLETED';
}
</script> </script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment