Thursday, September 22, 2022

Terminal and Full Disk Access

Jeff Johnson (tweet):

Many expert Mac users grant Full Disk Access to Terminal app, because the permissions dialogs quickly become very annoying when you try to do things in Terminal, as we’ve already seen above.

[…]

What you may not realize is that if you grant Full Disk Access to Terminal, you thereby provide Full Disk Access to every unsandboxed app on your Mac too! And how can this be? The reason is that unsandboxed apps can open executable shell scripts in Terminal, and those scripts will execute with the permissions not of the opening app but rather with the permissions of Terminal, i.e. Full Disk Access.

[…]

If you think the solution to this problem is simply to withhold Full Disk Access from Terminal: it’s not that simple! Every unsandboxed app effectively has all of the permissions of Terminal, whatever those permissions happen to be.

I don’t understand why Terminal executes shell script files in the first place. It doesn’t even prompt to confirm. Aside from the security implications—for what I think is not a commonly used feature, anyway—it also means that I sometimes execute a script by accident, double-clicking and expecting it (because of the icon) to open in a text editor.

Quinn the Eskimo:

MAC presents some serious challenges for scripting because scripts are run by interpreters and the system can’t distinguish file system operations done by the interpreter from those done by the script. For example, if you have a script that needs to manipulate files on your desktop, you wouldn’t want to give the interpreter that privilege because then any script could do that.

The easiest solution to this problem is to package your script as a standalone program that MAC can use for its tracking. This may be easy or hard depending on the specific scripting environment. For example, AppleScript makes it easy to export a script as a signed app, but that’s not true for shell scripts.

Sheldon15:

I find it’s a little backward approach to not have a robust way to test for FDA and instead handle errors resulting from the lack thereof. The problem is that sometimes you can’t distinguish errors resulting from the lack of FDA and other kinds of errors. Or you have a lengthy operation that you know will fail or will be incomplete without FDA and you want to tell the user in advance.

In my case, my app estimates size of a directory. Some subdirectories inside of it will not be counted due to the lack of FDA, and the overall size will not match Finder’s estimation. The scope of all folders protected from FDA is not clearly defined in the documentation, so I will not be able to detect when I have a lack of FDA or it’s a different kind of error. I can guess and recommend the user to add my app to FDA, but it’s confusing if he’s already done that and still sees the recommendation.

John Daniel (in 2019):

Full Disk Access isn’t very reliable either. You can do everything right and it still doesn’t work sometimes. You have to budget for this and provide documentation on how to remove an app, restart, re-add, and fallback to tccutil in the Terminal when all else fails.

Previously:

20 Comments RSS · Twitter

"I don’t understand why Terminal executes shell script files in the first place. It doesn’t even prompt to confirm."

Why would you want to take away double-clicking scripts?

Would you want the system to confirm every time you double-clicked an app?

Because I never double-click a script wanting it to run? AppleScript scripts don’t do that. Word files with macros don’t do that. Why should shell scripts?

Maybe you've never wanted that, but some Mac users have been doing it forever. ;-) And you can save an AppleScript as an app.

In essence, a shell script is really no different from a Mach-O executable. Just different code, different runtime.

Like quarantined apps, there should be an extended attribute which would make the Finder show an error message and not run the script on doubleclick. But it should be inverted: Only when that extended attribute is set a doubleclick would run the app - if missing the error message would appear.

Right-click should change the "Open" contextual menu to "Run Script". Cmd-right-click should add the extended attribute to enable doubleclicking for the future.

I don't appreciate unrelated comments I made over three years ago on the developer forums being re-posted in support of another ridiculous social media story about "macOS (in)security".

Maybe Full Disk Access was a little flaky when it was first introduced in macOS Mojave. But that has nothing do with any claims that it is a security risk today.

Terminal and command line tools are intended for developers and expert users. By default, Terminal does not have Full Disk Access. This is a setting that users must enable on purpose. Ironically enough, pretty much the only reason an end user is going to give Terminal Full Disk Access is because some Mac social media influencer told them to.

> ridiculous

What's ridiculous? Everything in my blog post is factual. Which fact are you disputing?

> social media story

My blog is not "social media". Neither is Michael's blog. I did tweet a link to my blog post, for those who don't follow my RSS feed.

> Terminal and command line tools are intended for developers and expert users. By default, Terminal does not have Full Disk Access.

Nobody disputes this. In fact I literally said "Many expert Mac users grant Full Disk Access to Terminal app".

My blog posts explains the full consequences of enabling Terminal full disk access, for those who were not aware of those consequences. What someone does with that information is up to them. If you read the last paragraph of my blog post, I clearly wasn't recommending panic. Quite the opposite, and I personally intend to keep full disk access enabled.

@Jeff But they are different because you can’t double-click a raw Mach-O executable to run it. And if you wrap it in a .app (like Quinn says) you can double-click it but it doesn’t inherit the access of the app that you opened it from. And neither has the icon of an editable text file.

@John I didn’t quote your comments in relation to a security risk. I’m just collecting information about Full Disk Access in general. My personal/developer/support experience is that your comments about it being flaky are still true today. One of the reasons that non-expert users sometimes need to give Terminal Full Disk Access (or disable SIP) is to troubleshoot when part of the system or TCC itself isn’t working properly. Since it isn’t a temporary elevation like sudo, my guess is that often time it gets left on. So I think the design of the system should not be assuming anything about who is using it.

Then use your own experiences. By quoting me, in this context, you are misrepresenting what I said.

The only thing I said about Full Disk Access in 2019 that I would still want quoted today is that part of the same paragraph that you omitted,

“Also, you aren't going to be able to avoid user confusion regardless of what you do. This is just really confusing for users.”

> you can’t double-click a raw Mach-O executable to run it.

Yes you can. It opens in Terminal and runs. :-)

> And neither has the icon of an editable text file.

Well, in order to be double-clickable, the executable shouldn't have a file extension. I was able to use the ".sh" file extension because my source code was manually opening the file, but Finder will actually open a .sh file for me in Xcode, which registers the public.shell-script content type in its Info plist.

Terminal registers the public.unix-executable content type with the role "Shell": "The app provides runtime services for other processes—for example, a Java applet viewer. The name of the document is the name of the hosted process (instead of the name of the app), and a new process is created for each document opened." https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html

@John I have added the date to the part I quoted to make the context more clear. The omitted part is the part I don’t agree with. :-) I mean, yes, someone will always be confused about anything, but there are ways this could be a lot better.

@Jeff Ah, you’re right about the raw Mach-O. I have definitely seen shell scripts with extensions open in Terminal, and I think it’s even the default for “.command” files.

Beatrix Willius

What does "Full Disk Access" actually do? I wasn't able to find the official docs. I know that it protects emails from Mail and some Safari files. What else does it "protect"?

I still check if there is a folder in the folder user/username/Library/Mail/VX. But that is rather brittle. Why isn't there a better way to check for "Full Disk Access"?

IMO Apple's security is for normal users. Power users or even developers are an afterthought. Telling users to distribute AppleScripts only in signed form is a joke, right? The internet is full of fun stories of problems with certificates.

I publish AppleScripts on my website. I recently added links to the AppleScripts so that they can be opened in ScriptEditor. The "security" is that the opened scripts show that they aren't codesigned. But if I click on the button in the window I get a new editable script. Yes, that makes everything secure.

If emails from Mail need to be protected why not emails from other email clients, too? Is it so bad that apps have full disk access? I need to be able to do my work. macOS is interfering with that more and more.

@Beatrix To understand what FDA does, you first need to understand what TCC protects against. In the simplest terms, it's there to protect your data against unauthorised access. You can think of unauthorised access in two ways:
1) A malicious app which claims to do one thing but steals your confidential info in the background (for example, a game generally shouldn't have access to your calendar, contacts information or email).
2) A genuine app which you trust but which turns out to have a vulnerability that can be exploited by an attacker to steal your data.

TCC aims to protect against scenario 1 by presenting a dialog box when said game attempts to raid your confidential info - the hope is that the user thinks "WTF? Why do you need access to that?" and then they click the deny option.

In general, TCC won't protect against scenario 2, although it can mitigate the damage caused. For example, if you have a third party app to manage your contacts, and you give it access, if that app gets compromised, the only thing the malicious actor can grab would be your contacts info. They wouldn't be able to get your calendar info or your email etc.

What Full Disk Access does is bypass the whole TCC system for specified apps. If you give FDA to that malicious game I mentioned earlier, it can rummage through your entire hard drive and take whatever it likes. Similarly, the compromised contacts app would be able to pilfer anything it likes.

Taking this one step further, to the Terminal, what's being said here is if it's been given FDA, it doesn't even need to have a vulnerability. Any scripts the user downloads from the internet will get full access to the system.

The one thing everyone here is forgetting though, is scripts (and Xcode projects for that matter) get the com.apple.quarantine bit set when they're downloaded by most software. What this means is double clicking them causes LaunchServices to display a warning to users.

Coming back to the issue @John brought up. I agree, it's disingenuous to quote something from years ago without saying it's an old comment (which I believe Michael has now added), but I have to say TCC is _still_ very flaky.

@Beatrix There is no documentation. The most authoritative information is I think what Quinn has posted in the forums. The way it works is not intuitive and subject to change. My recollection is that you can test whether a folder exists without having Full Disk Access.

@Mark If you go back to Jeff’s post, he’s talking about an app, which doesn’t have Full Disk Access, using Terminal to effectively get it anyway. So this is scenario 1, and the script file would not be downloaded and quarantined; it would be bundled in or created by the app, which has already been unquarantined. Gatekeeper does provide a level of protection against downloading a bare script, though I think it’s totally unexpected that such a script, if approved via the standard dialog, could potentially get Full Disk Access.

It seems to me that all of this was already solved securely in Unix by having multiple user accounts. In order to access mail, a person would have to run the mail tool as the user that can access mail. So you have to type a (different) password to run the mail tool, just as you should when you sudo.

Scripts work at the Unix level. If you prevent them from running, you probably break more stuff as they don't complete and leave the system in a broken state. That's why adding another security mechanism was a bad idea, because it leaves you with 2 bad choices: either you apply your mechanism to scripts, which breaks them or you don't and people complain about a security flaw.

I presume this mechanism was added either because "it's too much to expect users to know more than one password" or because someone who should, but didn't, know better wanted to boost his or her career.

Personally I always grant Terminal full disk access, and want all of the executables in it to have full disk access. I also have SIP fully disabled. I want to be able to do whatever I want with my computer, and I don't want macOS to get in the way. I don't want to grant every single app permission to access this and that, maybe with the exception of my microphone and camera. I am aware of all the security implications of doing so and have never had a problem. *knocks on wood*

I would fully disable most of TCC if I could, maybe the entire thing, especially given how annoying and broken it can be and how often it breaks apps, even apps that try to use it properly. But alas Apple does not allow that.

I just wish I could live my life without these things completely, but alas (again) I am a macOS software developer and so am forced to write apps that take account into these security features, and need test systems that have everything fully enabled.

I miss the days of macOS 10.6. Or even macOS 10.13.

"The easiest solution to this problem is to package your script as a standalone program that MAC can use for its tracking. This may be easy or hard depending on the specific scripting environment. For example, AppleScript makes it easy to export a script as a signed app, but that’s not true for shell scripts."

The venerable Platypus (https://sveinbjorn.org/platypus) is a utility for packaging scripts into .app executables, which I assume could be used for this purpose.

I'm with Bri and OUG, and I'll add that TCC is a contradiction in terms, just as the App Store is, for the simple reason that it doesn't actually give the user enough information to know whether an app is actually trustworthy. If users have to make highly generalised and blanket choices about privacy, what exactly is that saying about security? Painful as it is, you inevitably have to grant trust, because not doing so is a questionable defence of your privacy and a guarantee of reduced functionality, or else a certain indicator of system compromise that should and could have been prevented earlier. The idea that users can make trust decisions, without guarantees about the security isolation of an app (in a sandbox) is just silly and should never have been contemplated to begin with. In the world of general-purpose computing that is actually useful, there is implicit trust. If Apple wants a different world, they ought to build one, in the fashion of Qubes OS.

I personally use Lingon X to create an app from my scripts. And, just as Quinn writes in the linked forum post, that solves the problems for me with the permissions needed to run my scripts.

[…] Michael Tsai – Blog – Terminal and Full Disk Access What you may not realize is that if you grant Full Disk Access to Terminal, you thereby provide Full Disk Access to every unsandboxed app on your Mac too! And how can this be? The reason is that unsandboxed apps can open executable shell scripts in Terminal, and those scripts will execute with the permissions not of the opening app but rather with the permissions of Terminal, i.e. Full Disk Access. […]

Can’t you just give FDA to iTerm and not Terminal and have the best of all possible worlds?

Leave a Comment