-
-
Notifications
You must be signed in to change notification settings - Fork 679
Security
New in version 54, FluentFTP introduces a secure path sanitizer to protect against FTP command injection, traversal, encoding bypasses, and parser confusion attacks.
It is a mandatory feature and cannot be disabled for the protection of your application/server. If you feel certain security features are overtuned and wish to have them turned off, submit an issue and we will look into it.
The exact policies used by FluentFTP APIs are documented below.
TLDR: FTP commands can contain attack-sequences which can executed unintended commands on your FTP server. A new feature in FluentFTP protects against such attacks, using a process called "sanitization".
In FTP, file paths and file names are inserted directly into the plaintext FTP commands. If those values come from outside your code such as from user interface or an external file, they cannot be trusted. Without proper sanitization, the client can end up sending unintended commands which can end up attacking your FTP server.
Attackers can abuse this in simple ways. Newline characters can terminate one command and start another. Encoded values can hide dangerous input. Path traversal can move operations outside the intended directory. These inputs do not look harmful at first glance and can pass basic checks.
The client is often the place where these values are assembled. That makes it responsible for enforcing safe input. Relying on the server alone is not enough. The client may talk to different servers with different levels of validation. It may also be used in scripts, automation, or integrations where input is not controlled.
Developers should care because the impact is direct. A bad path can lead to file deletion, overwrite, or access to unintended locations. These issues are easy to introduce and hard to detect later.
Sanitizing FTP paths at the FTP client level is a simple way to prevent this entire class of problems, which is why FluentFTP has introduced these security measures.
The following policy applies to the majority of APIs:
- You cannot use directory traversal commands in FTP file paths (like
/../../myFolder/myFile.txt), if you do it will be converted to the current directory (like/myFolder/myFile.txt) - You cannot use sensitive unix-terminal characters in FTP file paths (
;,|,&) - You cannot use ASCII control chars in FTP file paths (
\0and0-32ASCII) - You cannot send multiline FTP paths to any API function
- You CAN use URL-encoded characters in FTP file paths, however they will be decoded and sent to the server
- You CAN use any slash (forward slash/backslash) in FTP file paths, however they will be normalized
- You CAN use whitespace around FTP file paths (like
myFile.txt), however it will be trimmed - You CAN use whitespace in FTP file names, it will be preserved (like
My File.txt)
Applies to the following APIs:
- FileExists
- DeleteFile
- MoveFile
- CompareFile
- TransferFile
- DirectoryExists
- CreateDirectory
- DeleteDirectory
- EmptyDirectory
- MoveDirectory
- TransferDirectory
- DownloadBytes
- DownloadDirectory
- DownloadFile
- DownloadStream
- UploadBytes
- UploadDirectory
- UploadFiles
- UploadStream
- GetChecksum
- GetFilePermissions
- GetFileSize
- GetListing
- GetModifiedTime
- GetNameListing
- GetObjectInfo
- SetFilePermissions
- SetModifiedTime
- SetWorkingDirectory
- Rename
- OpenAppend
- OpenRead
- OpenWrite
The following policy only applies to the Execute API:
- You cannot send multiple commands by using multiple lines in a single
Executecall - You CAN use sensitive unix-terminal characters, ASCII control chars in custom commands
- You CAN use URL-encoded characters in custom commands
Following is a list of FTP attacks and the means FluentFTP uses to protect against it.
-
Prevents command injection via CRLF or control chars
- Attackers can inject newlines to break the FTP command and append a new one (e.g.
DELE file) - This strips those characters -> stops command chaining completely
- Attackers can inject newlines to break the FTP command and append a new one (e.g.
-
Neutralizes encoded attacks (double-encoding bypass)
- Payloads like
%0D%0Aor%2E%2Ehide malicious input - Decoding first ensures these are revealed and then sanitized, not bypassed
- Payloads like
-
Blocks directory traversal (
..)- Prevents escaping intended directories (e.g. accessing parent folders)
- Stops attacks like
../../etc/passwdon FTP servers
-
Eliminates path confusion tricks (slashes)
- Mixed or repeated slashes (
\\,//) can bypass naive checks - Normalizing ensures validation is applied to a consistent path format
- Mixed or repeated slashes (
-
Prevents Unicode-based spoofing attacks
- Invisible/control Unicode chars can make paths look safe but behave differently
- Removing them stops deception and parsing inconsistencies
-
Avoids injection via whitespace manipulation
- Leading/trailing spaces can break parsing or be used to hide payloads
- Trimming ensures no ambiguity in how the path is interpreted
-
Prevents malformed path exploitation
- Collapsing redundant separators and cleaning structure avoids edge-case parser bugs
- Reduces attack surface from weird-but-valid path formats
-
Ensures consistent post-sanitization state
- Re-normalizing after decoding closes gaps where decoding reintroduces unsafe patterns
- Prevents
sanitize -> decode -> exploitbypass chains
-
Fail-safe fallback to root (
/)- If input becomes invalid/empty after cleaning -> defaults to
/ - Avoids undefined behavior or accidental execution on unintended paths
- If input becomes invalid/empty after cleaning -> defaults to
- Auto Connection
- Auto Reconnection
- FTP(S) Connection
- FTP(S) Connection using GnuTLS
- FTPS Proxies
- Custom Servers
- Custom Commands
- v40 Migration Guide