Repository navigation
ftp: require TLS on the data connection for implicit FTPS - #22995
Closed
MegaManSec wants to merge 1 commit into
Closed
MegaManSec wants to merge 1 commit into
MegaManSec wants to merge 1 commit into
Conversation
A bare ftps:// URL leaves CURLOPT_USE_SSL at CURLUSESSL_NONE, so a server rejecting PROT P got a cleartext data connection and CURLE_OK. Treat an implicit TLS scheme as CURLUSESSL_ALL when deciding the data connection protection level, without changing ftp_conn.use_ssl, which takes part in connection reuse matching. Test 1790.
MegaManSec
force-pushed
the
ftps-implicit-data-tls
branch
from
September 18, 2026 15:10
bcb019c to
17d78c9
Compare
There was a problem hiding this comment.
🟢 Approval recommended
The TLS enforcement is correct and covered by a focused regression test; only a minor connection-reuse inefficiency remains.
Pull request overview
Enforces encrypted data connections for implicit FTPS unless control-only TLS is explicitly selected.
Changes:
- Applies
CURLUSESSL_ALLsemantics to implicit FTPS. - Adds regression coverage for rejected
PROT P. - Registers the new test.
File summaries
| File | Description |
|---|---|
| tests/data/test1790 | Tests rejected FTPS data encryption. |
| tests/data/Makefile.am | Registers test 1790. |
| lib/ftp.c | Enforces implicit FTPS data TLS. |
Review details
Suppressed comments (1)
lib/ftp.c:3176
- The implicit
CURLUSESSL_ALLvalue is applied only while processingPROT.Curl_ftp_conns_match()still compares the rawftpc->use_sslvalues, so two requests to the same FTPS endpoint—one using the implicit default and one explicitly settingCURLUSESSL_ALL—cannot reuse each other's control connection even though their TLS behavior is now identical. Normalize the implicit FTPS default during setup, or compare effective values in the FTP connection matcher.
if(!ftpc->use_ssl && (conn->scheme->flags & PROTOPT_SSL))
return CURLUSESSL_ALL;
- Files reviewed: 3/3 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
bagder
approved these changes
Sep 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
curl ftps://host/fileleavesCURLOPT_USE_SSLatCURLUSESSL_NONE, so a server rejectingPROT Pgot a cleartext data connection and a successful transfer. Treat an implicit TLS scheme asCURLUSESSL_ALLwhen the application set no level; it now fails withCURLE_USE_SSL_FAILED.--ftp-ssl-controlis unaffected and restores the old behavior.Introduced in 4b62cd3 (curl 7.19.3).
LLM-archeology:
On whether the old behavior was intentional: before 7.19.3,
ftps_setup_connection()setconn->ssl[SECONDARYSOCKET].useandFTP_PBSZskippedPROTentirely, so a bareftps://URL always encrypted the data connection. 4b62cd3 replaced that assumption with realPROTnegotiation because FileZilla served clear-mode implicit control connections — a control-connection fix. But the refusal gate is keyed on the application-set level, added in c78ee11 as "CURLFTPSSL_ALL should make sure that the transfer fails if the data connection isn't set to encrypted properly", so once the scheme stopped implying a level nothing carried the requirement and a refusedPROT Pbecame silently acceptable.docs/cmdline-opts/ssl-reqd.mdstill promises the enforced behavior: "This option is unnecessary if you use a URL scheme that in itself implies immediate and implicit use of TLS, like for FTPS ... Such a transfer always fails if the TLS handshake does not work." That was written in 50750d0 (2022), long after the change.Caveat: a server offering implicit TLS but refusing
PROT Pused to transfer in cleartext and now fails with error 64.--ftp-ssl-controlstill selects that.