summaryrefslogtreecommitdiffstats
path: root/net/ftp/ftp_network_transaction.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/ftp/ftp_network_transaction.cc')
-rw-r--r--net/ftp/ftp_network_transaction.cc36
1 files changed, 33 insertions, 3 deletions
diff --git a/net/ftp/ftp_network_transaction.cc b/net/ftp/ftp_network_transaction.cc
index cf4a773..753aee2 100644
--- a/net/ftp/ftp_network_transaction.cc
+++ b/net/ftp/ftp_network_transaction.cc
@@ -24,6 +24,23 @@ const char kCRLF[] = "\r\n";
const int kCtrlBufLen = 1024;
+namespace {
+
+// Returns true if |input| can be safely used as a part of FTP command.
+bool IsValidFTPCommandString(const std::string& input) {
+ // RFC 959 only allows ASCII strings.
+ if (!IsStringASCII(input))
+ return false;
+
+ // Protect agains newline injection attack.
+ if (input.find_first_of("\r\n") != std::string::npos)
+ return false;
+
+ return true;
+}
+
+} // namespace
+
namespace net {
FtpNetworkTransaction::FtpNetworkTransaction(
@@ -58,9 +75,7 @@ int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info,
request_ = request_info;
if (request_->url.has_username()) {
- username_ = UTF8ToWide(request_->url.username());
- if (request_->url.has_password())
- password_ = UTF8ToWide(request_->url.password());
+ GetIdentityFromURL(request_->url, &username_, &password_);
} else {
username_ = L"anonymous";
password_ = L"chrome@example.com";
@@ -160,6 +175,13 @@ int FtpNetworkTransaction::SendFtpCommand(const std::string& command,
DCHECK(!write_command_buf_);
DCHECK(!write_buf_);
+ if (!IsValidFTPCommandString(command)) {
+ // Callers should validate the command themselves and return a more specific
+ // error code.
+ NOTREACHED();
+ return Stop(ERR_UNEXPECTED);
+ }
+
command_sent_ = cmd;
write_command_buf_ = new IOBufferWithSize(command.length() + 2);
@@ -518,6 +540,10 @@ int FtpNetworkTransaction::DoCtrlWriteComplete(int result) {
// USER Command.
int FtpNetworkTransaction::DoCtrlWriteUSER() {
std::string command = "USER " + WideToUTF8(username_);
+
+ if (!IsValidFTPCommandString(command))
+ return Stop(ERR_MALFORMED_IDENTITY);
+
next_state_ = STATE_CTRL_READ;
return SendFtpCommand(command, COMMAND_USER);
}
@@ -547,6 +573,10 @@ int FtpNetworkTransaction::ProcessResponseUSER(
// PASS command.
int FtpNetworkTransaction::DoCtrlWritePASS() {
std::string command = "PASS " + WideToUTF8(password_);
+
+ if (!IsValidFTPCommandString(command))
+ return Stop(ERR_MALFORMED_IDENTITY);
+
next_state_ = STATE_CTRL_READ;
return SendFtpCommand(command, COMMAND_PASS);
}