By John Gruber
Next-generation Apple device management for macOS, iOS, iPadOS, and tvOS. Request access.
For the sake of brevity I’ll assume you’re familiar with the full description of the “Safari shell script execution” exploit publicized Monday by Heise Online.
The trick here is that when you use the Finder’s Get Info window to assign a custom application with which to open a particular file, the Finder stores this information in a resource of type ‘usro’ that it adds to that file’s resource fork.
If you have the Mac OS X developer tools installed, you can use the
DeRez command-line tool to see this for yourself:
Start with any file which you know has no resource fork. Let’s say it’s named “testfile” and it’s on your desktop.
Get Info on that file using the Finder and change the “Open With” application to any other app than the default for that file.
In Terminal, type:
The output should show that the file now has a resource of type ‘usro’, and, if you look at the data of the resource, it begins with the full path to the application you chose to open the file with.
This feature has nothing to do with type and creator codes — which, contrary to popular misconception are not stored in resource forks, but are stored as HFS Plus metadata, just like the file name and modified and created dates. In fact, despite the fact that it uses the resource fork for storage, it has nothing to do with the classic Mac OS. This Finder behavior started with Mac OS X.
Normally, files are associated with a default application by means of either an HFS creator code, or by their file name extension. (And where by “default application” I mean the app that opens the file if you simply double-click it.) Creator codes have higher precedence than file name extensions, which means that, for example, you can have files with “.html” extensions map to your favorite web browser by default, but have “.html” files you’ve created yourself open by default in your favorite text editor by saving those files with the text editor’s creator code.
However, when you assign a custom “Open With” application in the Finder, this choice trumps all others. If you use the Get Info window to, say, specify that a particular file should open in Terminal by default, this choice is binding no matter what the file’s creator code and file name extension say.
And so that’s what is being exploited with the “Heise.jpg” example file. It doesn’t have a creator code, and the file name extension is “.jpg”, but the file also has a ‘usro’ resource specifying that the file should open in Terminal — or, specifically, with /Applications/Utilities/Terminal.app, which is why some people are recommending that you move or rename your copy of Terminal. If you change the path to the Terminal.app bundle, the ‘usro’ bundle will no longer work. (I do not recommend this, however, because moving or renaming Terminal might cause conflicts with future updates from Apple — and who’s to say there aren’t other apps that can be taken advantage of similarly?)
When Safari downloads a zip archive containing such a file, and Safari’s pref setting to “Open ‘Safe’ files after downloading” is turned on — as it is by default — what happens is that Safari looks at the expanded “Heise.jpg” file, sees that it doesn’t have a creator code, looks at the file name extensions and decides that “.jpg” is a “safe” file extension, and, so, it opens it.
The file name extension in this case is a lie. The file is not, in fact, a JPEG image. It’s a shell script. And so when it is “opened”, it’s opened by Terminal because of the ‘usro’ resource, and the shell script is run. Because “Heise.jpg” is a harmless proof-of-concept exploit, not a genuinely harmful Trojan horse, all it does is print the contents of your home folder and a few lines of text to the Terminal.
A harmful exploit using this very same technique could do just about anything to and with the entire contents of your home folder, however. This is not a fucking joke. But nor should you be overly concerned: if you turn off Safari’s “Open ‘safe’ files after downloading” preference — which I’ve recommended ever since the Launch Services imbroglio two years ago — you’re safe, unless you download such a file and open it manually. And if you use Camino or Firefox instead of Safari, you’re safe, too. (This is probably true for all browsers other than Safari, but I haven’t tested any others.)
There are a couple of things Apple could do about this (and these options are not exclusive):
Get rid of Safari’s “Open ‘safe’ files after downloading” preference. At the very least it should be turned off by default. Doing this would not only stop this particular exploit, but it would also cut off any future exploits from taking advantage of holes in the “safe files” algorithm.
If Apple had gotten rid of this preference two years ago, we wouldn’t be having this discussion now.
Greatly restrict what constitutes a “safe” file to a short list of known archive formats like zip files and disk images, and only pass such files off to the system’s default helper applications.
Change the implementation and format of the ‘usro’ resource such that it only applies to the user account used to create it. I.e. so that if I decide to open “testfile.jpg” with Terminal, it only applies to my user account, and so if I send the file to you, my custom “Open With” setting will be ignored when you open the file.
This would be an inconvenience for people who use the same file on multiple machines and who want these custom bindings to apply across machines. It’s an issue of balancing convenience versus security.
This entire exploit falls under the same category as a number of other possible Trojan horse techniques where you make an application or script look like an innocuous file by giving it a custom icon and a non-application-looking name. Except in this case, it’s not a fake icon pasted on the file, but instead, a “real” icon that Launch Services applies based on the file name extension.
So one problem is that while ‘usro’ resources have the highest precedence when determining which app will open a file, they have no bearing on the icon used to represent the file. However, the Finder does use this info when determining the file’s “kind”; here’s how it represents the “Heise.jpg” example file in column view; notice that it displays the file’s kind as “Terminal.app document”:1
But this is only a slightly different problem than that of custom icons pasted on applications so as to disguise them as innocuous documents — look no further than last week’s Oompa Loompa Trojan horse.
It boils down to this: you can’t safely double-click files from untrusted sources, and you never could. This is no different today on Mac OS X 10.4 than it was a decade ago on Mac OS 8 and 9.
Apple should consider addressing this in the Finder, by, say, adding some sort of visual treatment around application icons, which would provide some measure of warning for malware apps posing as documents — if there were some sort of halo around applications and you saw such a halo around a malware app posing as a JPEG, you’d have a visual indication that it’s not really a JPEG.
In the meantime, though, just be careful what you double-click.
It’ll say “Terminal document” instead of “Terminal.app document” on your computer, if you don’t have the Finder’s “Show all file extensions” preference turned on. ↩︎