Service:
ftpsvsftpdProFTPDFileZilla ServerProtocol:
TCPPort:
990Used for:
Carrying FTP commands and logins over an implicitly TLS-encrypted control channelPort 990 is the default port for FTPS (FTP over implicit TLS) — the control channel where an FTPS server takes the classic FTP command connection and wraps it in TLS from the very first byte. The login, the USER/PASS exchange, and commands like LIST, RETR, and STOR all travel inside an encrypted tunnel, so unlike plain FTP on port 21 nothing crosses the wire in cleartext. That encryption is exactly why port 990 gets treated as “safe” and quietly left exposed — but an FTPS listener still has a TLS stack to attack, an FTP server behind it, and all the usual FTP misconfigurations.
FTPS is not SFTP — this is the single most common mix-up, so it’s worth nailing up front. FTPS is ordinary FTP plus a TLS layer: implicit TLS on port 990, or explicit TLS (the AUTH TLS / STARTTLS upgrade) on port 21. SFTP is a completely different protocol that rides inside SSH on port 22 and shares nothing with FTP but the letters. If port 990 is open, you’re looking at FTPS; SFTP lives on 22.
Why It’s Open
FTPS exists to bolt encryption onto FTP without rewriting the workflow around it, so it turns up wherever “FTP over SSL” is a contractual requirement rather than a design choice: legacy B2B and EDI exchanges, managed file transfer (MFT) appliances, healthcare and finance partners, and overnight backup or batch jobs that push files to a partner. On Linux the daemon is usually vsftpd, ProFTPD, or Pure-FTPd with TLS switched on; on Windows it’s FileZilla Server, IIS FTP, or a commercial MFT product like Serv-U. Where port 990 answers, plain FTP on 21 and SFTP on 22 are usually one scan away — and the same host often exposes explicit FTPS on 21 as well.
Two FTPS details shape how you test it. First, implicit vs explicit: implicit FTPS (990) negotiates TLS before any FTP command is sent, while explicit FTPS (21) starts in cleartext and upgrades with AUTH TLS. Second, the data channel is separate from the control channel — active-mode data uses port 989 (ftps-data), and passive mode negotiates a high port. Because the control channel is encrypted, stateful firewalls and NAT can’t read the PASV/EPSV reply to open that data port on the fly, which is why FTPS deployments almost always need a fixed passive-port range punched through the firewall — a detail that often points straight at how carefully (or carelessly) the server was set up.
Common Risks
- Weak TLS protocols and ciphers. An FTPS listener that still offers SSLv3, TLS 1.0, 3DES, RC4, or export ciphers is exposed to downgrade and padding-oracle attacks — POODLE and Sweet32 apply to FTPS exactly as they do to HTTPS.
- Bad or ignored certificates. Expired, self-signed, or hostname-mismatched certs are common, and many FTPS clients are configured to skip certificate validation entirely. That turns an “encrypted” channel into an unauthenticated one an attacker on the path can transparently MITM.
- OpenSSL-class memory bugs. Heartbleed and its relatives leak private keys, session data, and plaintext credentials straight out of the FTPS process — encryption on the wire doesn’t help when the server hands you its memory.
- Anonymous access — encrypted, but still anonymous. TLS protects the transfer; it doesn’t decide who’s allowed in. An FTPS server that still accepts
anonymousgives away its file store over a perfectly encrypted channel. - Weak credentials and brute-force. Past the TLS handshake it’s the same FTP login, usually with no native rate limiting. Encryption hides the brute-force from a sniffer but does nothing to stop it.
- The same post-auth FTP surface as port 21. Writable roots over a web root, directory traversal, and buggy daemons behave exactly as they do on plain FTP — just inside a TLS wrapper that also hides the attack from network monitoring.
Want to save time on reporting?
Let PentestPad generate, track, and export your reports - automatically.

Enumeration & Testing
Detect the service and inspect the certificate
nmap -p 990 -sV --script ssl-cert,ssl-enum-ciphers <target>Check the TLS layer for Heartbleed and weak protocols
nmap -p 990 --script ssl-heartbleed,ssl-poodle,ssl-dh-params <target>Open the implicit-TLS control channel by hand
openssl s_client -connect <target>:990# after the handshake, type FTP commands directly:# USER anonymous# PASS anonymous@Connect with an implicit-FTPS client
curl -k -v ftps://<target>:990/lftp -e "set ssl:verify-certificate no; ls" ftps://<target>:990Full TLS assessment
testssl.sh <target>:990sslscan <target>:990Brute-force / anonymous check over FTPS
hydra -L users.txt -P passwords.txt ftps://<target>Heartbleed via Metasploit
msfconsole -quse auxiliary/scanner/ssl/openssl_heartbleedset RHOSTS <target>set RPORT 990runRecord every open port 990, weak cipher, bad certificate, and credential that works as you go, so the evidence lands in the pentest report instead of a scratch terminal you’ll lose.
What to Look For
| Checkpoint | What it means |
|---|---|
| SSLv3 / TLS 1.0 or 3DES/RC4 offered | Weak crypto — POODLE, Sweet32, and downgrade exposure |
| Expired, self-signed, or mismatched cert | Clients that ignore it can be MITM’d — encryption without authentication |
| OpenSSL 1.0.1 through 1.0.1g | Heartbleed — keys and credentials readable from the listener |
| Anonymous login accepted | Public file access, still a leak even over TLS |
230 Login successful with default creds |
Immediate account access behind the encryption |
| Broken data channel / no passive-port range | TLS bolted on hastily — expect more misconfiguration |
Explicit FTPS also on port 21 (AUTH TLS) |
STARTTLS command-injection surface that implicit 990 avoids |
Known CVEs and Exploits
- CVE-2014-0160 — Heartbleed. A buffer over-read in OpenSSL 1.0.1 through 1.0.1g lets an unauthenticated attacker read up to 64KB of the FTPS server’s memory per heartbeat — private keys, session data, and freshly typed credentials. CVSS 7.5. It hits any FTPS daemon built on the vulnerable OpenSSL (vsftpd, ProFTPD
mod_tls, Pure-FTPd). Test withnmap --script ssl-heartbleedor Metasploit’sauxiliary/scanner/ssl/openssl_heartbleed; PoC on Exploit-DB 32745. - CVE-2011-1575 — Pure-FTPd before 1.0.30. A STARTTLS plaintext command-injection flaw (the same class as CVE-2011-0411): the server buffers a cleartext command sent before the handshake and executes it after TLS is in place, so a MITM can inject commands into the “encrypted” session even when the client checks the certificate. CVSS v2 5.8. Note this targets explicit FTPS (
AUTH TLSon port 21) — implicit FTPS on port 990 has no cleartext phase to inject into, so it sidesteps this whole class. - CVE-2019-19269 / CVE-2019-19270 — ProFTPD
mod_tlsthrough 1.3.6b. In a TLS client-certificate (mutual-auth) setup,tls_verify_crldereferences a NULL pointer on an empty CRL and crashes the connection (19269, DoS, CVSS 4.9); 19270 checks the wrong CRL field, so revoked client certificates are still accepted — a certificate-revocation bypass on the FTPS listener. - CVE-2009-0884 — FileZilla Server before 0.9.31. A buffer overflow triggered by crafted SSL/TLS packets lets a remote attacker crash the server (DoS). CVSS v2 4.3 — old, but a clean example of the FTPS TLS layer itself being the bug, not the FTP logic behind it.
FTPS is the hardened variant, so its listener CVEs skew toward TLS-layer disclosure and DoS rather than the outright RCEs that plague cleartext FTP. Two caveats: the weak-protocol/cipher problems — POODLE (CVE-2014-3566, SSLv3) and Sweet32 (CVE-2016-2183, 3DES) — affect any FTPS server still offering legacy TLS; and once you’re past the TLS layer, the big FTP-server RCEs (the vsftpd 2.3.4 backdoor CVE-2011-2523, ProFTPD mod_copy CVE-2015-3306) apply exactly as they do on port 21, just inside encryption.
Mitigation
- Enforce modern TLS. Require TLS 1.2+ (ideally 1.3), disable SSLv3/TLS 1.0/1.1, and drop 3DES, RC4, and export ciphers. Serve a valid, CA-signed certificate for the correct hostname and make sure clients actually validate it — an ignored cert is no protection.
- Require authentication — no anonymous. TLS decides how the session is protected, not who gets in. Disable anonymous FTPS unless a directory is deliberately public, and if it is, make it read-only and keep it outside any web root.
- Strong credentials and rate limiting. Use unique strong passwords, kill vendor defaults, and put fail2ban or the daemon’s own throttling on repeated login failures — encryption doesn’t slow a brute-force down.
- Prefer SFTP, or FTPS done properly. SFTP over SSH (port 22) is simpler to firewall (one port, one channel) and avoids FTPS’s split control/data model. If FTPS is mandated, validate certificates and pin a fixed passive-data-port range rather than opening a broad range.
- Patch and restrict the FTP server. Keep OpenSSL and the FTPS daemon current (Heartbleed alone is reason enough), chroot users to their home directory, and drop write access where it isn’t needed.
- Don’t expose port 990 to the internet. Firewall it to known clients or a management range. If nothing needs FTPS, stop the daemon and confirm the port is closed with a rescan.
Real-World Example
When Heartbleed (CVE-2014-0160) went public in April 2014, the headlines were all about HTTPS — but the bug was in OpenSSL, so every service linked against the vulnerable library was exposed, and FTPS servers running vsftpd, ProFTPD, or Pure-FTPd with TLS were squarely in scope. A single crafted heartbeat to port 990 could read up to 64KB of the server’s memory back, with no login and no entry in the FTP logs — enough to lift the server’s private key, active session data, or the plaintext password of whoever had just authenticated. It’s the cleanest illustration of the FTPS trap: the channel was flawlessly encrypted and completely compromised at the same time, because the weakness lived in the TLS library, not on the wire. It’s also a reminder that “FTPS” and “SFTP” are not interchangeable safety labels — SolarWinds’ own Serv-U Secure FTP shipped its worst RCE (CVE-2021-35211, CISA-listed, exploited in the wild by a China-based group in 2021) not in its FTPS listener at all, but in its SSH/SFTP stack.
FAQ
What is port 990 used for?
Port 990 is the default control channel for FTPS — FTP wrapped in implicit TLS. It carries the login and FTP commands (LIST, RETR, STOR) inside an encrypted tunnel, while the file data moves over a separate channel on port 989 in active mode or a negotiated high port in passive mode.
Is FTPS the same as SFTP?
No — this is the most common confusion. FTPS is FTP plus a TLS layer (implicit on 990, or explicit AUTH TLS on 21). SFTP is an entirely separate protocol that runs inside SSH on port 22. They solve the same problem but share no code, no port, and no protocol — an open port 990 is FTPS, never SFTP.
What’s the difference between implicit FTPS (990) and explicit FTPS (21)?
Implicit FTPS negotiates TLS immediately on connecting to port 990 — the whole session is encrypted from the first byte. Explicit FTPS connects to port 21 in cleartext and then issues AUTH TLS to upgrade. Implicit is the older, “always-on” model; explicit is more firewall-friendly but has a brief plaintext window that has led to STARTTLS command-injection bugs.
Is port 990 dangerous?
Less immediately dangerous than cleartext FTP on 21, because credentials aren’t sniffable — but not “safe.” The TLS stack can be weak (old protocols, bad certs, Heartbleed), and once past encryption it’s the same FTP surface: anonymous access, weak passwords, and writable directories. Treat an internet-facing port 990 as something to harden and lock down, not to trust because it says “secure.”
What port does FTPS use for data?
The control channel is 990; the data channel is separate. In active mode the server uses port 989 (ftps-data); in passive mode it negotiates a high port from a configured range. Because the control channel is encrypted, firewalls can’t read the passive-port negotiation, so FTPS servers usually need a fixed passive range explicitly allowed through.
How do I secure or close port 990?
Enforce TLS 1.2+ with a valid certificate and strong ciphers, disable anonymous login, use strong credentials with rate limiting, and patch OpenSSL and the FTPS daemon. Firewall port 990 to trusted clients, or move file transfer to SFTP on port 22. If nothing needs FTPS, stop the service and rescan with nmap -p 990 <target> to confirm it’s closed.
TL;DR
- Service: FTPS (FTP over implicit TLS) control channel
- Default port: 990/TCP (data on 989/TCP or a negotiated passive high port)
- Not SFTP: SFTP is a separate, SSH-based protocol on port 22 — FTPS is FTP + TLS
- Biggest risk: weak TLS/certs, Heartbleed-class listener bugs, and the same anonymous/weak-credential FTP surface as port 21 — just encrypted
- Mitigation: TLS 1.2+ with valid certs, no anonymous, strong creds + rate-limit, patch the server, don’t expose to the internet (or move to SFTP)