Adam Knight the codepoet, whom I link to quite often from here, has an article out on Mac Geekery, ominously called “How a Malformed Installer Package Can Crack Mac OS X“:
There exists a pretty significant interface problem with the Apple Installer program such that any package requesting admin access via the AdminAuthorization key, when run in an admin user account, is given full root-level access without providing the user with a password prompt during the install. This is even explained in Apple’s Installer documentation as proper behavior. The distinction between the AdminAuthorization and RootAuthorization keys is, simply, whether or not the admin user is prompted for a password; the end powers are exactly the same and it is up to the creator of the package as to if he will be kind enough to ask for a password…
Well, at first glance this looks like a pretty serious security hole. Let’s see what that Apple documentation says about this:
This is actually quite clear. If the installer package asks for the same level of privileges that the logged-in user already has, authorization is not required; meaning, it won’t ask for a password. Which makes sense; after all, to log in as root or as an administrator you must know the root or an administrator’s password to start with – usually. If the packages needs higher privileges to do its stuff, the user will be “prompted for authorization”. This autorization will be used for two purposes: setting permissions on the installed files, and for running pre- and post-installation scripts. We’re concerned only about the second purpose. Before going into that, let me explain a few things.
First of all, using an installer package is pretty much, nowadays, a good thing only when you’re installing something that messes with the system’s folders, or that executes scripts that do restricted things. Installing a kernel extension, updating the system frameworks, setting up servers and startup/login items are common examples. It’s frightfully infra-dig to make a package just to install your application in /Applications. In other words, just the presence of an installer package on a disk image should be pretty much an indication that something uncommon will happen if you double-click it.
So, the common perception is that for an installer package to mess with the restricted system folders is that it should ask for root authorization, and therefore you’ll be asked for a password – since you’re not running as root to begin with. Or shouldn’t be; the root account comes disabled by default on Mac OS X. And since most packages do it this way, this perception is reinforced; it’s become pretty much automatic to double-click on a package, type in your administrator password at the prompt, and “boom” (can’t remember who says that ).
So Adam strongly recommends:
Run as a normal user. Open files you trust. Stick to that and you’ll be fine.
Read his recommendations and follow at least some of them. I’d add: use Charles Srstka’s excellent Pacifist software to see what’s being installed, and where, before running the Installer – for one, Pacifist doesn’t run pre- and post-installation scripts contained in the package, so it’s not an Installer replacement.
The tricky part comes when the package asks for admin authorization. Mac OS X installs the first user as an administrator, and it’s required to have an administrator account present – after all, if you had none, the system would become quite unmodifiable. So, the recommended practice is to set up your system in this first account, then set up a second non-admin user account and use this for your normal activities; switch back to the admin account only when installing software.
Unfortunately, Apple seems to have found this confusing for “normal” users, and I’d tend to agree. A significant amount of explanation would have to be inserted into the setup application, especially as this not-normally-used “user” would also have a home folder where stuff would not be visible by the day-to-day user. There’s even the option of setting the machine to boot automatically into a certain user, and I’d say many non-technical users click this to speed up booting and to avoid having to remember their password every day. Unfortunately, as a side-effect of these circumstances, most users are running as an administrator without having had to type in the administrator password at all.
Now let’s suppose you get a (underhandedly malicious) installer package and double-click on it without examining its contents beforehand. You think it can’t mess up much as it will ask for a password if it does anything serious, right?
Wrong. True, it will ask for a password if it wants root authorization – but then, you’re already conditioned to type in your password anyway. But if it asks for admin authorization and you’re already running as an admin, it won’t ask for a password at all, and merrily use the admin authorization you gave it (by logging in!) to muck about with your system.
Now wait a minute. Why does this admin authorization which is not root authorization let the installer run scripts as root, as Adam proved by a test package? Isn’t that a serious bug and security hole, as he claims?
Well, yes and no. The answer lies in a file called /etc/authorization. This is an XML file in property list format which defines the various rights a process can ask for when using the Authorization Framework, and defines a set of rules that are applied when this happens. The principles involved are quite complex, and I’m still learning to understand them fully. Here’s a paragraph from that documentation:
When a user who is a member of the admin group logs on to the system, for example, the user’s credential (that is, the fact that they have entered a valid admin user name and password) is saved in the global credentials cache. Then when this user attempts to modify a system preference, Security Server finds the credential in the cache and does not display an authentication dialog.
which confirms what I said above. And later on:
Not all installers require authorization – only those that need special privileges to copy files to restricted directories, make changes to restricted files, or set setuid bits.
An installer is a special case because unlike other applications, an installer is usually run only once. Due to the limited use, Authorization Services provides a function to invoke your installer to run with root privileges. It is up to the user to determine if the installer is from a trusted source.
So far so good; but why in, practice, do admin privileges mean “run as root”? Well, in that XML file we have the following section:
<key>system.privilege.admin</key>
<dict>
<key>allow-root</key>
<true/>
...
<key>group</key>
<string>admin</string>
<key>shared</key>
<false/>
<key>timeout</key>
<integer>300</integer>
</dict>
Translating this into a slightly less geeky form, this is the autorization right requested by the AuthorizationExecuteWithPrivileges() call, which is the one used by the Installer. It can be granted to users of the “admin” group, is granted automatically to the root user, and times out in 5 minutes. AuthorizationExecuteWithPrivileges(), in turn, is the system call to run a script as root; which is allowed for administrators, as we’ve seen.
In other words, everything is certainly “behaving as expected”; it’s not a bug, it’s a mistaken assumption: “anything that runs as root will ask for authentication when run by an admin user”. That’s certainly not true. However, I don’t deny that the Installer could be more explicit here, either not calling AuthorizationExecuteWithPrivileges() for its scripts when admin authorization is asked for (which might break some existing packages), or by showing a separate alert at the beginning, saying “this package will run its scripts as root”. Let’s suggest this to Apple and see what happens…