How one man could have hacked every Mac developer (73% of them, anyway)

Here’s a cool fact: Macs run Unix.

OK, in some ways that’s only very loosely true, when you think of all the non-Unixy stuff on top of the Darwin base layer, and we welcome your comments below to explain just how carelessly loose we have been…

…but Macs are Unix computers – in fact, they’re UNIX computers – at least if they’re running a currently supported macOS, and that means lots of cool, useful, well-known and powerful tools for sysadmins, developers and power users, preinstalled and ready to go.

Here’s an eclectic, alphabetically-ordered subset of the utility programs that arrive on every brand new Mac, taken from the /usr/bin directory:

   2to3          indent         ruby                                          
   awk           json_pp        sed                                     
   banner        krb5-config    tail                                     
   caffeinate    less           umask                                   
   dc            man            vi                          
   env           nice           which                            
   file          openssl        xargs                                
   grep          perl           yes                             
   head          quota          zip                              

If Perl and Ruby don’t @float your $boat (language-war comments below, please, no need to hold back), you can also choose from other open-source programming languages such as Java, PHP, Python and Tcl.

Despite all this ready-to-go choice, however, Mac developers miss the ease with which their Linux chums can grab additional open source software packages.

Linux distros famously come with one or more package managers that can be told, with a single command in a terminal window, to call home, find the latest version of super-useful toolkit X, fetch it and install it.

No need to hunt down the X project online, find the right fork, identify the latest version, download the source code, inspect it, apply any needed tweaks, configure it, compile it, and install it.

Slackware, Debian, Gentoo, Arch and Void Linux, for a five-fold variety, have slackpkg, apt-get, portage, pacman and xbps – tools that make it easy not only to grab new software packages but also to keep your existing ones up to date.

Running a command-line package manager isn’t quite as easy to learn as clicking About This MacSoftware Update..., but package managers generally give you much better control over and visibility into the updating process.

Importantly, package managers make it easy not only to fetch new programs you need, but also to remove them when you don’t need them any more.

For example, if I were suddenly to decide that I needed Emacs on my Slackware box after all, this would do it:

   > slackpkg search emacs
   . . .
   The list below shows all packages matching 'emacs'

   [uninstalled] emacs-26.1-x86_64-1
   [uninstalled] emacspeak-38.0-x86_64-1

   > slackpkg install emacs
   -- and when I recovered my equanimity once more

   > slackpkg remove emacs

It’s not quite the same thing as a package manager, but if you’re comfortable in a terminal window on your Mac, try the command softwareupdate --help or man softwareupdate. Once you’re used to softwareupdate --list, softwareupdate --download and sudo softwareupdate --install, you’ll never use the App Store GUI again for macOS patches.

Package managers for Macs

Over the years, various open source package managers have appeared on the Mac scene, aiming to bring the convenience and familiarity of tools like slackpkg and apt-get to the macOS ecosystem.

The big three are MacPorts, Homebrew and Fink – they’re as similar as they are different – and according to an entirely unscientific Naked Security poll on Twitter, they’re used in these proportions:

As the poll suggests, a significant proportion of Mac users use one of these tools [40%+11%+4% = 55%], and 73% of those that do are using Homebrew [40%/(40%+11%+4%) = 73%].

Package managers generally do some or all of these things whenever you install a new package or update an existing one:

  • Download the needed code, scripts and executable files from an online repository.
  • Run some of these downloaded scripts and programs immediately to build or configure the package.
  • Install the newly-prepared packages so they are available for use.
  • Repeat the above steps for any other packages that are needed to make the chosen package work.
  • Repeat the above steps for any packages needed by the packages needed to make the chosen package work.
  • And so on. (This recursive download of packages as an automatic by-product is known in the jargon as satisfying the dependencies).

In most cases, at least some of the stages in the package manager’s workflow require root access, meaning that the package manager software runs as root at least some of the time, notably when copying new files into place.

What could go wrong?

You can see that there’s a lot that could go wrong here.

One hacker with write access to the repository, or one buggy package in its midst, even briefly, and thousands of users – perhaps even hundreds of thousands – might end up with a deeply unpleasant surprise.

Ironically, in the event of a rogue modification to a package that is very widely depended upon, users who are more punctilious about keeping up to date will be more likely to download and therefore to be affected by a malicious dependency.

How safe are package manager ecosystems?

The potential impact of a well-thought-out hack into one of the many package management ecosystems out there is a pet concern of security researcher Eric Holmes.

Hacks against the very repositories that many of us rely upon for software updates are known in the jargon as supply-chain attacks – after all, the modern supply chain often doesn’t involve any factories, ships, trains, inventories, trucks, pallets or forklifts.

So, Holmes decided to take a look at the supply chain for Homebrew, or Brew for short – we’re guessing he picked Brew not only because he knew it was the most popular amongst the Mac community, but also because he uses it himself.

The results were, in a word, salutary.

For the details, be sure to read Holmes’s article (it’s superbly compact and clear, though some technical background to source code repositories and web authentication is helpful).

Very simply put, Holmes found a Homebrew server – one that was intended to be public – that tracks the details of which packages have been modified, rebuilt and tested recently.

Most companies with build-and-test servers of this sort (Homebrew uses a popular open source toolkit called Jenkins) keep them private, but it’s hard to fault Homebrew for being transparent in this way – the packages it builds and distributes are themselves open, free and public.

Unfortunately, Holmes quickly found a web page he could click through to that turned up this:

Don’t worry if tables of this sort aren’t something you’re used to – the important part is that Homebrew had accidentally leaked what’s called an API token.

This is essentially an access key that, when inserted into web requests made to Homebrew’s GitHub account, tells the server what access rights to grant to those requests.

API tokens are unique, so they can’t be guessed; they’re typically acquired by logging in with a username, password and perhaps a two-factor authentication code, so they’re only available to trusted users; they’re only ever sent over encrypted HTTPS connections, so they’re kept away from prying eyes…

…and they’re very definitely not meant to be published!

Longstoryshort, Holmes was able to copy this API token, paste it into his own web requests, and get read-and-write access to much of Homebrew’s GitHub content.

As he explains in his post, he could have hacked pretty much any Homebrew package, thereby infecting any and every Mac user who installed or updated that package – or, of course, any other package that depended on it.

And, as Holmes wryly pointed out, the most downloaded package in the last 30 days at Homebrew is itself all about cybersecurity: openssl, with more than half-a-million installs last month.

That’s a lot of Brew users – and by implication a lot of developers who themselves build software for distribution to other people – whom he could have put on the spot.

What to do?

If you’re a Brew user, there’s no need for alarm and no immediate action you need to take.

Holmes disclosed this responsibly to the Homebrew crew, who fixed the issue right away – within a few hours, in fact – and published a short, frank and informative disclosure notice.

As in the case of Gentoo’s recent supply-chain breach, the disclosure notice is worth reading whether the incident directly affects you or not.

Howebrew included some security precautions that the team is planning to add, and why.

So, that’s our suggestion in this case: read Homebrew’s security disclosure.

Supply-chain attacks can have wide-reaching effects, so ask yourself, “What can I and my own organisation learn from this?”