FTP Without TLS (ftplib.FTP)

MEDIUM

ftplib.FTP() transmits data and credentials in plaintext. Use ftplib.FTP_TLS() or SFTP (via paramiko) for secure file transfer.

Rule Information

Language
Python
Category
Python Core
Author
Shivasurya
Shivasurya
Last Updated
2026-03-22
Tags
pythonftpftplibplaintextfile-transferCWE-319OWASP-A02
CWE References

Interactive Playground

Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.

pathfinder scan --ruleset python/PYTHON-LANG-SEC-063 --project .
1
2
3
4
5
6
7
rule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

About This Rule

Understanding the vulnerability and how it is detected

Python's ftplib.FTP() class implements the FTP protocol, which transmits all data including login credentials (username and password), commands, and file contents in plaintext. FTP was designed in an era when network security was not a concern and has never supported encryption natively in its base form.

An attacker who can observe network traffic (on the same network segment, via ARP poisoning, or at any network hop between client and server) can capture FTP credentials and all transferred file contents.

Secure alternatives include: - ftplib.FTP_TLS(): FTP over TLS (FTPS/FTPES), which encrypts the control connection and can encrypt the data connection. Requires server support. - paramiko (SSH/SFTP): SFTP over SSH is generally more secure and widely supported. - HTTPS-based file transfer for web-accessible files.

Security Implications

Potential attack scenarios if this vulnerability is exploited

1

Plaintext Credential Transmission

FTP LOGIN command transmits the username and password in plaintext. Any network observer can capture these credentials and use them to access the FTP server, modify files, exfiltrate data, or plant malicious files.

2

File Content Interception

All files transferred via FTP (uploads and downloads) are transmitted without encryption. Sensitive documents, configuration files, database backups, and any other file content is visible to network observers.

3

Command Injection via Plaintext Control Channel

FTP uses a separate control channel for commands. An attacker who can intercept and modify the control channel can inject arbitrary FTP commands, redirect file transfers to attacker-controlled locations, or delete files.

4

Passive Mode Data Connection Hijacking

In passive mode FTP, the server provides an IP and port for the data connection. An attacker with network access can intercept the passive mode response and replace the data connection endpoint, hijacking the file transfer.

How to Fix

Recommended remediation steps

  • 1Replace ftplib.FTP() with ftplib.FTP_TLS() for encrypted FTP, and call ftp.prot_p() to enable TLS on the data connection as well as the control connection.
  • 2Prefer SFTP (SSH File Transfer Protocol) via paramiko over FTPS for new implementations, as SSH key-based authentication is more secure than FTP passwords.
  • 3If the FTP server does not support TLS, migrate the server to support FTPS or SFTP rather than accepting plaintext FTP.
  • 4Never transmit credentials over plain FTP; use key-based authentication with SFTP or TLS certificates with FTPS.
  • 5Consider HTTPS-based file transfer (S3, web API) as a modern alternative that avoids FTP protocol complexity entirely.

Detection Scope

How Code Pathfinder analyzes your code for this vulnerability

This rule detects calls to ftplib.FTP() constructor in Python source code. All call sites are flagged since plain FTP always transmits credentials and data in plaintext. ftplib.FTP_TLS() is the secure alternative and is not flagged.

Compliance & Standards

Industry frameworks and regulations that require detection of this vulnerability

PCI DSS v4.0
Requirement 4.2.1 - Use strong cryptography for cardholder data transmission; FTP is explicitly prohibited
OWASP Top 10
A02:2021 - Cryptographic Failures
NIST SP 800-52 Revision 2
Only approved encrypted protocols permitted for sensitive data transmission
HIPAA Security Rule
45 CFR 164.312(e) - Technical safeguards for data in transit

References

External resources and documentation

Similar Rules

Explore related security rules for Python

Frequently Asked Questions

Common questions about FTP Without TLS (ftplib.FTP)

FTPS (FTP over SSL/TLS) is FTP with TLS added to the control and data connections. It uses ports 21 (explicit TLS via AUTH TLS) or 990 (implicit TLS). SFTP is the SSH File Transfer Protocol and runs over SSH (port 22). They are completely different protocols. SFTP is generally preferred for new implementations due to SSH's mature security model and widespread key-based authentication support.
FTP_TLS() with ssl.create_default_context() is much safer than plain FTP. However, ensure ftp.prot_p() is called to enable TLS on the data connection in addition to the control connection. Without prot_p(), only the control connection (credentials and commands) is encrypted; file contents may still be transmitted in plaintext.
FTP has decades of legacy support in file sharing, hosting control panels, and industrial equipment. Many legacy systems support only FTP. For legacy integration, use FTPS if the server supports it. If the server only supports plain FTP, document the risk and limit the sensitive data transmitted over FTP, then plan migration.
Yes. PCI DSS v4.0 Requirement 4.2.1 prohibits unencrypted protocols including FTP for transmitting cardholder data. Systems in scope for PCI DSS must use FTPS, SFTP, or HTTPS for all file transfers involving cardholder data.
Step 1: Check if the FTP server supports FTPS (try connecting with FTP_TLS()). If yes, migrate to FTP_TLS() immediately. Step 2: If the server supports SSH, use paramiko SFTP. Step 3: For web-accessible files, use HTTPS-based upload/download APIs. Step 4: For legacy systems that only support plain FTP, isolate them on a private network, use a VPN/SSH tunnel, and plan server migration.
Tunneling FTP through SSH (ssh -L) provides encryption for the control connection. However, passive mode FTP data connections may bypass the tunnel depending on configuration. SFTP is simpler and more reliable than FTP-over-SSH-tunnel.

New feature

Get these findings posted directly on your GitHub pull requests

The FTP Without TLS (ftplib.FTP) rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.

See how it works