Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(632)

Unified Diff: net/proxy/proxy_service_unittest.cc

Issue 1996773002: Sanitize https:// URLs before sending them to PAC scripts. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed Matt's feedback Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« net/proxy/proxy_service.cc ('K') | « net/proxy/proxy_service.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/proxy/proxy_service_unittest.cc
diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc
index a0db685aaba34234fca5ac5a7afcf567a214b7eb..5cd57e79074f8f61b46194dc13c1db593a8589d0 100644
--- a/net/proxy/proxy_service_unittest.cc
+++ b/net/proxy/proxy_service_unittest.cc
@@ -3480,4 +3480,212 @@ TEST_F(ProxyServiceTest, SynchronousWithFixedConfiguration) {
EXPECT_EQ(0u, factory->pending_requests().size());
}
+// This test checks that URLs are sanitized before being passed on to the proxy
+// resolver (i.e. PAC scripts).
+TEST_F(ProxyServiceTest, SanitizeUrlsBeforeResolving) {
mmenke 2016/05/20 17:40:23 Didn't realize you had this sort of test as well,
eroman 2016/05/20 21:23:53 Done. I agree that is a better approach. All of th
+ MockProxyConfigService* config_service =
+ new MockProxyConfigService("http://foopy/proxy.pac");
+ MockAsyncProxyResolver resolver;
+ MockAsyncProxyResolverFactory* factory =
+ new MockAsyncProxyResolverFactory(false);
+
+ ProxyService service(base::WrapUnique(config_service),
+ base::WrapUnique(factory), nullptr);
+
+ // Request 1 ----------------------------------------------------------------
+
+ // This URL includes a lot of different parts (some of these are expected to
+ // be stripped).
+ GURL url1("http://username:password@www.google.com:8080/path?query#fragment");
+ GURL sanitized_url1("http://www.google.com:8080/path?query");
+
+ ProxyInfo info1;
+ TestCompletionCallback callback1;
+ int rv = service.ResolveProxy(url1, std::string(), LOAD_NORMAL, &info1,
+ callback1.callback(), nullptr, nullptr,
+ BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ // First step is to download the PAC script.
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+ factory->pending_requests()[0]->script_data()->url());
+ factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);
+
+ ASSERT_EQ(1u, resolver.pending_requests().size());
+ // Ensure that the sanitized URL was sent to the proxy resolver (not the full
+ // URL).
+ EXPECT_EQ(sanitized_url1, resolver.pending_requests()[0]->url());
+
+ // Complete the request.
+ resolver.pending_requests()[0]->results()->UsePacString("DIRECT");
+ resolver.pending_requests()[0]->CompleteNow(OK);
+ EXPECT_EQ(OK, callback1.WaitForResult());
+ EXPECT_TRUE(info1.is_direct());
+
+ // Request 2 ----------------------------------------------------------------
+
+ // Start another request. This time the URL is https://, so a different
+ // sanitization strategy should be used.
+ GURL url2(
+ "https://username:password@www.google.com:8080/path?query#fragment");
+ GURL sanitized_url2("https://www.google.com:8080/");
+
+ ProxyInfo info2;
+ TestCompletionCallback callback2;
+ rv = service.ResolveProxy(url2, std::string(), LOAD_NORMAL, &info2,
+ callback2.callback(), nullptr, nullptr,
+ BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ ASSERT_EQ(1u, resolver.pending_requests().size());
+ // Ensure that the sanitized URL was sent to the proxy resolver (not the full
+ // URL).
+ EXPECT_EQ(sanitized_url2, resolver.pending_requests()[0]->url());
+
+ // Complete the request.
+ resolver.pending_requests()[0]->results()->UsePacString("DIRECT");
+ resolver.pending_requests()[0]->CompleteNow(OK);
+ EXPECT_EQ(OK, callback2.WaitForResult());
+ EXPECT_TRUE(info2.is_direct());
+
+ // Request 3 ----------------------------------------------------------------
+
+ // Change the sanitization policy.
+ service.set_sanitize_url_policy(ProxyService::SanitizeUrlPolicy::UNSAFE);
+
+ // Start another request. This is the same as request 2, however the expected
+ // sanitized URL is different (includes the path and query).
+ GURL url3 = url2;
+ GURL sanitized_url3("https://www.google.com:8080/path?query");
+
+ ProxyInfo info3;
+ TestCompletionCallback callback3;
+ rv = service.ResolveProxy(url3, std::string(), LOAD_NORMAL, &info3,
+ callback3.callback(), nullptr, nullptr,
+ BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ ASSERT_EQ(1u, resolver.pending_requests().size());
+ // Ensure that the sanitized URL was sent to the proxy resolver (not the full
+ // URL).
+ EXPECT_EQ(sanitized_url3, resolver.pending_requests()[0]->url());
+
+ // Complete the request.
+ resolver.pending_requests()[0]->results()->UsePacString("DIRECT");
+ resolver.pending_requests()[0]->CompleteNow(OK);
+ EXPECT_EQ(OK, callback3.WaitForResult());
+ EXPECT_TRUE(info3.is_direct());
+}
+
+// Tests SanitizeUrlForPacScript() using input URLs that have a
+// non-cryptographic scheme (i.e. http://). The sanitized result is consistent
+// regardless of the stripping mode selected.
+TEST_F(ProxyServiceTest, SanitizeUrlForPacScriptNonCryptographic) {
+ const struct {
+ const char* raw_url;
+ const char* sanitized_url;
+ } kTests[] = {
+ // Embedded identity is stripped.
+ {
+ "http://foo:bar@example.com/", "http://example.com/",
+ },
+ {
+ "ftp://foo:bar@example.com/", "ftp://example.com/",
mmenke 2016/05/20 17:40:23 Seems like we should have a test with an FTP URL w
eroman 2016/05/20 21:23:53 Done.
+ },
+ // Reference fragment is stripped.
+ {
+ "http://example.com/blah#hello", "http://example.com/blah",
+ },
+ // Query parameters are NOT stripped.
+ {
+ "http://example.com/foo/bar/baz?hello",
+ "http://example.com/foo/bar/baz?hello",
+ },
+ // Fragment is stripped, but path and query are left intact.
+ {
+ "http://foo:bar@example.com/foo/bar/baz?hello#sigh",
+ "http://example.com/foo/bar/baz?hello",
+ },
+ // Port numbers are not affected.
+ {
+ "http://example.com:88/hi", "http://example.com:88/hi",
+ },
+ };
+
+ for (const auto& test : kTests) {
+ // The result of SanitizeUrlForPacScript() is the same regardless of the
+ // second parameter (sanitization mode), since the input URLs do not use a
+ // cryptographic scheme.
+ GURL raw_url(test.raw_url);
+ ASSERT_TRUE(raw_url.is_valid());
+ EXPECT_FALSE(raw_url.SchemeIsCryptographic());
+
+ EXPECT_EQ(GURL(test.sanitized_url),
+ ProxyService::SanitizeUrl(
+ raw_url, ProxyService::SanitizeUrlPolicy::UNSAFE));
+
+ EXPECT_EQ(GURL(test.sanitized_url),
+ ProxyService::SanitizeUrl(raw_url,
+ ProxyService::SanitizeUrlPolicy::SAFE));
+ }
+}
+
+// Tests SanitizeUrlForPacScript() using input URLs that have a cryptographic
+// schemes (i.e. https://). The sanitized result differs depending
+// on the sanitization mode chosen.
+TEST_F(ProxyServiceTest, SanitizeUrlForPacScriptCryptographic) {
+ const struct {
+ // Input URL.
+ const char* raw_url;
+
+ // Output URL when stripping of cryptographic URLs is disabled.
+ const char* sanitized_url_unstripped;
+
+ // Output URL when stripping of cryptographic URLs is enabled.
+ const char* sanitized_url;
+ } kTests[] = {
+ // Embedded identity is always stripped.
+ {
+ "https://foo:bar@example.com/", "https://example.com/",
+ "https://example.com/",
+ },
+ // Fragments are always stripped, but stripping path is conditional on the
+ // mode.
+ {
+ "https://example.com/blah#hello", "https://example.com/blah",
+ "https://example.com/",
+ },
+ // Stripping the query is conditional on the mode.
+ {
+ "https://example.com/foo/bar/baz?hello",
+ "https://example.com/foo/bar/baz?hello", "https://example.com/",
mmenke 2016/05/20 17:40:23 Suggest no path on this one (Well...a path of "/",
eroman 2016/05/20 21:23:53 Done.
+ },
+ // The embedded identity and fragment is always stripped, however path and
+ // query are conditional on the stripping mode.
+ {
+ "https://foo:bar@example.com/foo/bar/baz?hello#sigh",
+ "https://example.com/foo/bar/baz?hello", "https://example.com/",
+ },
+ // The URL's port should not be stripped.
+ {
+ "https://example.com:88/hi", "https://example.com:88/hi",
+ "https://example.com:88/",
+ },
mmenke 2016/05/20 17:40:23 Suggest also having a wss test. Could add a ws te
eroman 2016/05/20 21:23:53 Done.
+ };
+
+ for (const auto& test : kTests) {
+ GURL raw_url(test.raw_url);
+ ASSERT_TRUE(raw_url.is_valid());
+ EXPECT_TRUE(raw_url.SchemeIsCryptographic());
+
+ EXPECT_EQ(GURL(test.sanitized_url_unstripped),
+ ProxyService::SanitizeUrl(
+ raw_url, ProxyService::SanitizeUrlPolicy::UNSAFE));
+
+ EXPECT_EQ(GURL(test.sanitized_url),
+ ProxyService::SanitizeUrl(raw_url,
+ ProxyService::SanitizeUrlPolicy::SAFE));
+ }
+}
+
} // namespace net
« net/proxy/proxy_service.cc ('K') | « net/proxy/proxy_service.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698