An FTP and FTPS client for .NET & .NET Standard, optimized for speed. Provides extensive FTP commands, File uploads/downloads, SSL/TLS connections, Automatic directory listing parsing, File hashing/checksums, File permissions/CHMOD, FTP proxies, FXP support, UTF-8 support, Async/await support, Powershell support and more. Written entirely in C#.
MIT License
3.14k
stars
657
forks
source link
FtpClient throws exception from log masking when Credentials.UserName is empty #1649
FluentFTP Version: 51.1.0
Framework: Happens on both .NET Framework 4.8 and .NET 8.0
Summary
LogMaskModule tries to replace UserName instances with a fixed mask string, but if UserName is empty, then String.Replace throws an exception saying "System.ArgumentException: 'The value cannot be an empty string. (Parameter 'oldValue')'".
Applicability
FTP spec (RFC 959) doesn't allow an empty username, but there's nothing that prevents an FTP client from sending an empty USER command, and the server from accepting it.
Ideally, LogMaskModule should check for empty UserName and skip processing. FtpClient should reject an empty UserName directly in the constructor preferably with a manual override for exotic use cases.
Workarounds
Enable LogUserName = true in configuration (which isn't ideal)
Repro:
Here's a simple test program. Removing NetworkCredential parameter fixes this issue:
using System.Net;
using FluentFTP;
namespace FtpTest
{
internal class Program
{
static async Task Main(string[] args)
{
string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Directory.CreateDirectory(path);
Console.WriteLine($"Server path: {path}");
var server = new Zhaobang.FtpServer.FtpServer(new IPEndPoint(IPAddress.Loopback, 4444), path);
var cancelTokenSource = new CancellationTokenSource();
var cancelToken = cancelTokenSource.Token;
var task = Task.Run(() => server.RunAsync(cancelToken));
var client = new AsyncFtpClient("127.0.0.1", new NetworkCredential()
{
UserName = "",
Password = "",
},4444, new FtpConfig()
{
LogToConsole = true,
});
if (!await client.DirectoryExists("test/mest"))
{
await client.CreateDirectory("test/mest", force: true);
}
await client.UploadFile("D:\\test.txt", "test/test.txt");
Console.WriteLine("DONE! ");
cancelTokenSource.Cancel();
Console.WriteLine("CANCELLED TOO! ");
await task;
}
}
}
FluentFTP Version: 51.1.0 Framework: Happens on both .NET Framework 4.8 and .NET 8.0
Summary
LogMaskModule
tries to replaceUserName
instances with a fixed mask string, but ifUserName
is empty, thenString.Replace
throws an exception saying "System.ArgumentException: 'The value cannot be an empty string. (Parameter 'oldValue')'".Applicability
FTP spec (RFC 959) doesn't allow an empty username, but there's nothing that prevents an FTP client from sending an empty
USER
command, and the server from accepting it.Ideally,
LogMaskModule
should check for empty UserName and skip processing.FtpClient
should reject an empty UserName directly in the constructor preferably with a manual override for exotic use cases.Workarounds
LogUserName = true
in configuration (which isn't ideal)Repro:
Here's a simple test program. Removing NetworkCredential parameter fixes this issue: