I'm afraid I'm just not clear as to why Xcode needs those shims. Those shims are designed to launch a dialog box prompting to install the command line tools. They are completely unnecessary, because as it turns out bash does this better, but for that you need v4.

The fact that there is a dialog box that comes up means that if a script is run then it should fail if it can't find git. Preinstalled shim executables are a bad idea - I would hope that bash not find git rather than automatically ask to install the XCode Command Line Tools!

>> Who switches the PATH to /usr/bin:/bin or /usr/local/bin:/usr/bin:/bin?

> Someone who's writing a script and wants to be insulated from potentially-malicious entries in PATH. Or shells or shell-like programs executed without any PATH provided at all, which can happen if you invoke them with `env -i`.

Then they should point PATH to the standard locations where the software is installed, which would indicate that if there was a further directory then they should append it to the end. Not entirely sure what the issue is with this.

Somewhat ironically, if they are expecting that git would be the one run in the /usr/bin directory they would find that the shim bypassed the PATH variable entirely and executed a binary in an entirely different directory. So much for their concern over insulating from potentially-malicious entries by reducing the search path to /usr/local/bin and /usr/bin...

>> Perhaps because of the same reason why on the average server it's suggested that to keep your attack surface as low as possible you only install the minimum set of utilities and services necessary for the server to be operational?

> Huh? What does any of this have to do with attack surface? These tools are on the system regardless, moving them into a different directory has no bearing on attack surface.

I never said that. You cannot remove the shims, so in essence you haven't removed the software. If you are forced into keep the shims, even though you don't want to have git installed, you still potentially have it installed. The shims themselves have the most opaque way of finding git I can possibly think of... the following is what I found on it:

"Below are what I've deduced its order of checks to be. Remember that this checking is the responsibility of libxcselect. xcode-select simply provides a way of manipulating some configuration on the system that libxcselect will make use of when one of these shim commands is run, or if xcrun is invoked directly by the user with specific options.

If the DEVELOPER_DIR environment variable is set when a command is run, any system default will be overridden.

If a symlink at /var/db/xcode_select_link is present and it points to a valid developer dir within an Xcode or the CLI tools, this will be used. This symlink will be created when running xcode-select -s <path> if <path> is either an alternate Xcode path or that of the CLI tools, and there is already an Xcode.app in /Applications.

If neither of the above are set, and the path /Applications/Xcode.app/Contents/Developer is present, this is used.
If no Xcode path as above are set, but CLI tools are installed in /Library/Developer/CommandLineTools, these are selected." [1]

Note that those are from shims preinstalled on OS X.

So basically, the shim runs xcrun, which relies on xcode-select. xcode-select allows you to set the environment variable
DEVELOPER_DIR to whereever you want, and will switch to this directory then run the tool from within there. That's a remarkably convoluted process, and frankly I can see how easy it would be to increase attack surface.

The issue I have with the shims is that there is no way of removing them by default.

>> and if a non-system binary is replaced and that binary is installed in a location away from system binaries you can put it back?

>..what? I genuinely can't figure out what you're trying to say with this sentence.

I did explain myself poorly there. All I'm saying is that any non-critical software can be installed into a different directory. Currently it is installed in a system directory where the entire point of it being immutable is to ensure that no binaries can be modified by anyone other than the installer service, yet those shims bypass this by ensuring that if you run the shim, you actually are running an entirely different executable located on a part of the system where malware does have write access. Thus defeating the purpose of SIP!

>> Not to mention that only under the current situation only Apple can supply security updates to a third party took they don't actually maintain?

> Congratulations, you've just described how every third-party component bundled with the system works.

Indeed - and I'm saying it's a bad situation if the software has gaping security holes that don't get patched quickly or effectively by Apple - and you can't remove it easily.

> > And they can't be as quick as a system administrator who wants to remove it entirely?

> That's completely nonsense. Any "system administrator" that believes these tools should be removed from OS X should be fired for incompetence. These are shims, and their entire point is to provide a predictable location within the default PATH for a bunch of tools that are actually bundled inside Xcode or the standalone Command Line Tools download. If you don't want to have git/clang/etc on your system, don't install Xcode or the standalone Command Line Tools. It's that simple.

What? If you want to install OS X command line tools, then use:

xcode-select --install

What doesn't make any sense is to have a "shim" that invokes a dialog box when you invoke the command to install the XCode command line tools. What you currently have is a situation where if someone has an environment where they might be invoking git in a script then it runs a program that invokes an interactive dialog box prompting to install the XCode command line tools! Aside from the sheer silliness of a dialog box in a shell script, there are a lot of shell scripts that expect that if the system can't find the binary, then the shell will invoke an error which they catch and handle gracefully.

> So really this pretty much boils down to "if you don't want developer tools on your system, don't install the developer tools". All that you'll have are a set of shims that offer to install the developer tools if you try and run them (which I hope you can see is a pretty sensible suggestion, and is akin to how linux distros often suggest packages you can install when you try and execute commands that don't exist).

No, what it boils down to is that if you have a tool that you don't want installed on the system you get a shim binary that executes regardless and makes it harder to handle in your average shell script.

What you don't realise when you speak about how Linux distros suggest packages is that they don't actually run a new executable, they are actually using a version of bash equal to or higher than version 4, which looks for the shell function command_not_found_handle. This gives a number of suggestions and returns status code 127, which is the same code that you get if the shell can't find the executable or that function. [2] There is absolutely no executing of a specific binary, it's all completely done within the user's bash environment.

Apple currently use bash 3.2.57(1) on my OS X El Capitan system, so they don't have the ability to leverage this feature. Which is a shame as it is far and away more sensible that preemptively installing a shim in the directory where the binary would normally be. Which, as far as I can tell, was an inelegant hack done by the XCode install team all the way back in OS X Maverick and preloaded on OS X. It's not scalable in any way, as it relies on the Operating System to know about all possible software that might or might not be installed by the user - having shims for each and every possible 3rd-party program in existence is hardly a good strategy - and not one that Linux distributions follow.

1. https://macops.ca/developer-binaries-on-os-x-xcode-select-an...

2. https://www.gnu.org/software/bash/manual/bashref.html#Comman...