On FTP

This thread has been locked by a moderator; it no longer accepts new replies.

Questions about FTP crop up from time-to-time here on DevForums. In most cases I write a general “don’t use FTP” response, but I don’t have time to go into all the details. I’ve created this post as a place to collect all of those details, so I can reference them in other threads.

IMPORTANT Apple’s official position on FTP is:

  • All our FTP APIs have been deprecated, and you should avoid using deprecated APIs.

  • Apple has been slowly removing FTP support from the user-facing parts of our system. The most recent example of this is that we removed the ftp command-line tool in macOS 10.13.

  • You should avoid the FTP protocol and look to adopt more modern alternatives.

The rest of this post is an informational explanation of the overall FTP picture.

This post is locked so I can keep it focused. If you have questions or comments, please do create a new thread with the Network tag and I’ll respond there.

Don’t Use FTP

FTP is a very old and very crufty protocol. Certain things that seem obvious to us now — like being able to create a GUI client that reliably shows a directory listing in a platform-independent manner — are not possible to do in FTP. However, by far the biggest problem with FTP is that it provides no security [1]. Specifically, the FTP protocol:

  • Provides no on-the-wire privacy, so anyone can see the data you transfer

  • Provides no client-authenticates-server authentication, so you have no idea whether you’re talking to the right server

  • Provides no data integrity, allowing an attacker to munge your data in transit

  • Transfers user names and passwords in the clear

Using FTP for anonymous downloads may be acceptable (see the note below) but most other uses of FTP are completely inappropriate for the modern Internet.

IMPORTANT You should only use FTP for anonymous downloads if you have an independent way to check the integrity of the data you’ve downloaded. For example, if you’re downloading a software update, you could use code signing to check its integrity. If you don’t check the integrity of the data you’ve downloaded, an attacker could substitute a malicious download instead. This would be especially bad in, say, the software update case.

These fundamental problems with the FTP protocol mean that it’s not a priority for Apple. This is reflected in the available APIs, which is the subject of the next section.

FTP APIs

Apple provides two FTP APIs:

  • All Apple platforms provide FTP downloads via NSURLSession

  • Most Apple platforms (everything except watchOS) support CFFTPStream, which allows for directory listings, downloads, uploads, and directory creation.

All of these FTP APIs are now deprecated:

  • NSURLSession was deprecated for the purposes of FTP in the 2022 SDKs (macOS 13, {i{,Pad},tv}OS 16, watchOS 9) [2].

  • CFFTPStream was deprecated in the 2016 SDKs (macOS 10.11, {i{,Pad},tv}OS 9).

CFFTPStream still works about as well as it ever did, which is not particularly well. Specifically:

  • There is at least one known crashing bug (r. 35745763), albeit one that occurs quite infrequently.

  • There are clear implementation limitations — like the fact that CFFTPCreateParsedResourceListing assumes a MacRoman text encoding (r. 7420589) — that will not be fixed.

If you’re looking for an example of how to use these APIs, check out SimpleFTPSample.

Note This sample has not been updated since 2013 and is unlikely to ever be updated given Apple’s position on FTP.

The FTP support in NSURLSession has significant limitations:

  • NSURLSession only supports FTP downloads; there is no support for uploads or any other FTP operations

  • NSURLSession does not support resumable FTP downloads [3]

  • NSURLSession background sessions only support HTTP and HTTPS, so you can’t run FTP downloads in the background on iOS

If Apple’s FTP APIs are insufficient for your needs, you’ll need to write or acquire your own FTP library. Before you do that, however, consider switching to an alternative protocol. After all, if you’re going to go to the trouble of importing a large FTP library into your code base, you might as well import a library for a better protocol. The next section discusses some options in this space.

Alternative Protocols

There are numerous better alternatives to FTP:

  • HTTPS is by far the best alternative to FTP, offering good security, good APIs on Apple platforms, good server support, and good network compatibility. Implementing traditional FTP operations over HTTPS can be a bit tricky. One possible way forward is to enable DAV extensions on the server.

  • FTPS is FTP over TLS (aka SSL). While FTPS adds security to the protocol, which is very important, it still inherits many of FTP’s other problems. Personally I try to avoid this protocol.

  • SFTP is a file transfer protocol that’s completely unrelated to FTP. It runs over SSH, making it a great alternative in many of the ad hoc setups that traditionally use FTP.

Apple does not have an API for either FTPS or SFTP, although on macOS you may be able to make some headway by invoking the sftp command-line tool.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] In another thread someone asked me about FTP’s other problems, those not related to security, so let’s talk about that.

One of FTP’s implicit design goals was to provide cross-platform support that exposes the target platform. You can think of FTP as being kinda like telnet. When you telnet from Unix to VMS, it doesn’t aim to abstract away VMS commands, so that you can type Unix commands at the VMS prompt. Rather, you’re expected to run VMS commands. FTP is (a bit) like that.

This choice made sense back when the FTP protocol was invented. Folks were expecting to use FTP via a command-line client, so there was a human in the loop. If they ran a command and it produced VMS-like output, that was fine because they knew that they were FTPing into a VMS machine.

However, most users today are using GUI clients, and this design choice makes it very hard to create a general GUI client for FTP. Let’s consider the simple problem of getting the contents of a directory. When you send an FTP LIST command, the server would historically run the platform native directory list command and pipe the results back to you. To create a GUI client you have to parse that data to extract the file names. Doing that is a serious challenge. Indeed, just the first step, working out the text encoding, is a challenge. Many FTP servers use UTF-8, but some use ISO-Latin-1, some use other standard encodings, some use Windows code pages, and so on.

I say “historically” above because there have been various efforts to standardise this stuff, both in the RFCs and in individual server implementations. However, if you’re building a general client you can’t rely on these efforts. After all, the reason why folks continue to use FTP is because of it widespread support.

[2] To quote the macOS 13 Ventura Release Notes:

FTP is deprecated for URLSession and related APIs. Please adopt modern secure networking protocols such as HTTPS. (92623659)

[3] Although you can implement resumable downloads using the lower-level CFFTPStream API, courtesy of the kCFStreamPropertyFTPFileTransferOffset property.

Revision History

  • 2024-04-15 Added a footnote about FTP’s other problems. Made other minor editorial changes.

  • 2022-08-09 Noted that the FTP support in NSURLSession is now deprecated. Made other minor editorial changes.

  • 2021-04-06 Fixed the formatting. Fixed some links.

  • 2018-02-23 First posted.

Boost
On FTP
 
 
Q