-
-
Notifications
You must be signed in to change notification settings - Fork 681
Security
New in version 54, FluentFTP introduces a secure path sanitizer to protect against FTP command injection, directory traversal attacks, encoding bypasses, and parser confusion attacks.
It is enabled by default, but can be disabled at a granular level if it affects your FTP file uploads/downloads. It is highly recommended to keep all sanitizer features enabled for the protection of your application/server.
TLDR: FTP commands can contain attack-sequences which can execute 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.
-
Config.SanitizeControlChars - Prevents FTP command-injection attacks by removing any characters after an ASCII control character in filepaths. Anything after these chars is truncated:
\0,0-32ASCII,;,|,\r,\n. Default: Enabled. -
Config.SanitizeMultiline - Prevents FTP command-injection attacks by only retaining the first line of any multiline path. This prevents attackers from adding payloads consisting of rogue commands after the first line. Anything after these chars is truncated:
\rand\n. Default: Enabled. -
Config.SanitizeUnicodeSpoofing - Prevents FTP Unicode-spoofing attacks by removing Unicode control characters from filepaths. Default: Enabled.
-
Config.SanitizeTraversal - Prevents FTP URL-encoded attacks by performing a URL decode on filepaths. Default: Enabled.
-
Config.SanitizeUrlEncoding - Prevents FTP directory-traversal attacks by removing directory traversal prefixes in filepaths. This prevents attackers from using relative FTP filepaths to access sensitive folders outside the scope of their current FTP folder. Default: Enabled.
The following policy applies to the majority of APIs:
| # | Policy | Setting to disable it |
|---|---|---|
| 1 | 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) |
SanitizeTraversal |
| 2 | You cannot use sensitive unix-terminal characters in FTP file paths (;,|) |
SanitizeControlChars |
| 3 | You cannot use ASCII control chars in FTP file paths (\0 and 0-32 ASCII) |
SanitizeControlChars |
| 4 | You cannot send multiline FTP paths to any API function (only the first line will be kept, and the rest truncated) |
SanitizeMultiline and SanitizeControlChars
|
| 5 | You CAN use URL-encoded characters in FTP file paths, however they will be decoded and sent to the server | SanitizeUnicodeSpoofing |
| 6 | You CAN use any slash (forward slash/backslash) in FTP file paths, however they will be normalized | Always enabled |
| 7 | You CAN use whitespace around FTP file paths (like myFile.txt ), however it will be trimmed |
Always enabled |
| 8 | You CAN use whitespace in FTP file names, it will be preserved (like My File.txt) |
Always enabled |
| 9 | You CAN use relative FTP paths (paths not starting with /) |
Always enabled |
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
- Credits for discovering and disclosing the CRLF vulnerability go to Pramod Kumar.
- Credits for discovering the URL-encoded, directory traversal, path confusion and Unicode-spoofing vulnerabilities go to Robin Rodricks.
- Auto Connection
- Auto Reconnection
- FTP(S) Connection
- FTP(S) Connection using GnuTLS
- FTPS Proxies
- Custom Servers
- Custom Commands
- v40 Migration Guide