summaryrefslogtreecommitdiffstats
path: root/net/base
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-16 00:20:29 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-16 00:20:29 +0000
commit99d69350703593e50793dc6017cc67d31b54fe33 (patch)
tree6576111f7904b644fc3e547312f4ae9eef4872a0 /net/base
parent4066f2d8f1e778029f1663546d39efb221ffc590 (diff)
downloadchromium_src-99d69350703593e50793dc6017cc67d31b54fe33.zip
chromium_src-99d69350703593e50793dc6017cc67d31b54fe33.tar.gz
chromium_src-99d69350703593e50793dc6017cc67d31b54fe33.tar.bz2
More correctly handle username and password in FtpNetworkTransaction.
- prevent newline injection attacks - correctly unescape credentials provided in the URL TEST=Covered by net_unittests. http://crbug.com/20336 Review URL: http://codereview.chromium.org/183046 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26305 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base')
-rw-r--r--net/base/net_error_list.h3
-rw-r--r--net/base/net_util.cc8
-rw-r--r--net/base/net_util.h6
-rw-r--r--net/base/net_util_unittest.cc65
4 files changed, 82 insertions, 0 deletions
diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h
index c750295..745227e 100644
--- a/net/base/net_error_list.h
+++ b/net/base/net_error_list.h
@@ -257,6 +257,9 @@ NET_ERROR(PAC_SCRIPT_FAILED, -327)
// satisfy the range requested.
NET_ERROR(REQUEST_RANGE_NOT_SATISFIABLE, -328)
+// The identity used for authentication is invalid.
+NET_ERROR(MALFORMED_IDENTITY, -329)
+
// The cache does not have the requested entry.
NET_ERROR(CACHE_MISS, -400)
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index 5f6b548..b8c8add 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -1169,6 +1169,14 @@ std::string GetHostName() {
return std::string(buffer);
}
+void GetIdentityFromURL(const GURL& url,
+ std::wstring* username,
+ std::wstring* password) {
+ UnescapeRule::Type flags = UnescapeRule::SPACES;
+ *username = UnescapeAndDecodeUTF8URLComponent(url.username(), flags);
+ *password = UnescapeAndDecodeUTF8URLComponent(url.password(), flags);
+}
+
void AppendFormattedHost(const GURL& url,
const std::wstring& languages,
std::wstring* output,
diff --git a/net/base/net_util.h b/net/base/net_util.h
index 89386bf8..4d7e0aa 100644
--- a/net/base/net_util.h
+++ b/net/base/net_util.h
@@ -77,6 +77,12 @@ std::string NetAddressToString(const struct addrinfo* net_address);
// Returns the hostname of the current system. Returns empty string on failure.
std::string GetHostName();
+// Extracts the unescaped username/password from |url|, saving the results
+// into |*username| and |*password|.
+void GetIdentityFromURL(const GURL& url,
+ std::wstring* username,
+ std::wstring* password);
+
// Return the value of the HTTP response header with name 'name'. 'headers'
// should be in the format that URLRequest::GetResponseHeaders() returns.
// Returns the empty string if the header is not found.
diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc
index 2047b14..6a01ec9 100644
--- a/net/base/net_util_unittest.cc
+++ b/net/base/net_util_unittest.cc
@@ -530,6 +530,71 @@ TEST(NetUtilTest, FileURLConversion) {
EXPECT_FALSE(net::FileURLToFilePath(GURL("filefoobar"), &output));
}
+TEST(NetUtilTest, GetIdentityFromURL) {
+ struct {
+ const char* input_url;
+ const wchar_t* expected_username;
+ const wchar_t* expected_password;
+ } tests[] = {
+ {
+ "http://username:password@google.com",
+ L"username",
+ L"password",
+ },
+ { // Test for http://crbug.com/19200
+ "http://username:p@ssword@google.com",
+ L"username",
+ L"p@ssword",
+ },
+ { // Username contains %20.
+ "http://use rname:password@google.com",
+ L"use rname",
+ L"password",
+ },
+ { // Keep %00 as is.
+ "http://use%00rname:password@google.com",
+ L"use%00rname",
+ L"password",
+ },
+ { // Use a '+' in the username.
+ "http://use+rname:password@google.com",
+ L"use+rname",
+ L"password",
+ },
+ { // Use a '&' in the password.
+ "http://username:p&ssword@google.com",
+ L"username",
+ L"p&ssword",
+ },
+ };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ SCOPED_TRACE(StringPrintf("Test[%d]: %s", i, tests[i].input_url));
+ GURL url(tests[i].input_url);
+
+ std::wstring username, password;
+ net::GetIdentityFromURL(url, &username, &password);
+
+ EXPECT_EQ(tests[i].expected_username, username);
+ EXPECT_EQ(tests[i].expected_password, password);
+ }
+}
+
+// Try extracting a username which was encoded with UTF8.
+TEST(NetUtilTest, GetIdentityFromURL_UTF8) {
+ GURL url(WideToUTF16(L"http://foo:\x4f60\x597d@blah.com"));
+
+ EXPECT_EQ("foo", url.username());
+ EXPECT_EQ("%E4%BD%A0%E5%A5%BD", url.password());
+
+ // Extract the unescaped identity.
+ std::wstring username, password;
+ net::GetIdentityFromURL(url, &username, &password);
+
+ // Verify that it was decoded as UTF8.
+ EXPECT_EQ(L"foo", username);
+ EXPECT_EQ(L"\x4f60\x597d", password);
+}
+
// Just a bunch of fake headers.
const wchar_t* google_headers =
L"HTTP/1.1 200 OK\n"