Wandering Thoughts archives

2014-11-05

(Probably) Why Bash imports functions from the environment

In the wake of the Shellshock issues, a lot of people started asking why Bash even had a feature to import functions from the environment. The obvious answer is to allow subshell Bashes to inherit functions from parent shells. Now, you can come up with some clever uses for this feature (eg to pass very complex options down from parents to children), but as it happens I have my own views about why this feature probably originally came to exist.

Let us rewind to a time very long ago, like 1989 (when this feature was introduced). In 1989, Unix computers were slow. Very slow. They were slow to read files, especially if you might be reading your files over the network from a congested NFS server, and they were slow to parse and process files once they were loaded. This was the era in which shells were importing more and more commands as builtins, because not having to load and execute programs for things like test could significantly speed up your life. A similar logic drove the use of shell functions instead of shell scripts; shell functions were already resident and didn't require the overhead of starting a new shell and so on and so forth.

So there you are, with your environment all set up in Bash and you want to start an interactive subshell (from inside your editor, as a new screen window, starting a new xterm, or any number of other ways). Bash supports a per-shell startup file in .bashrc, so you could define all your shell functions in it and be done. But if you did this, your new subshell would have to open and read and parse and process your .bashrc. Slowly. In fact every new subshell would have to do this and on a slow system the idea of cutting out almost all of this overhead is very attractive (doing so really will make your new subshell start faster).

Bash already exports and imports plain environment variables, but those aren't all you might define in your .bashrc; you might also define shell functions. If a subshell could be passed shell functions from the environment, you could bypass that expensive read of .bashrc by pre-setting the entire environment in your initial shell and then just having them inherit it all. On small, congested 1989 era hardware (and even for years afterwards) you could get a nice speed boost here.

(This speed boost was especially important because Bash was already a fairly big and thus slow shell by 1989 standards.)

By the way, importing shell functions from the environment on startup is such a good idea that it was implemented at least twice; once in Bash and once in Tom Duff's rc shell for Plan 9.

(I don't know for sure which one was first but I suspect it was rc.)

unix/BashWhyFunctionImport written at 23:31:47; Add Comment

The weakness of doing authentication over a side channel

Yesterday I mentioned our method of authenticating NFS client hosts; fundamentally it operates by every so often verifying that the client host knows a secret. Suppose that we had a slightly improved version of this, where the NFS fileserver holds an authenticated TCP connection open with the client and periodically exchanges authenticated and encrypted packets with it; the simple version of this would just be a SSH connection with SSH level keepalives. Is this a reasonably secure system or is it attackable?

(A system without a continuous authentication connection is trivially attackable; get the real client to authenticate once, force it off the network, and replace it with your imposter client.)

Unfortunately, yes it is. Take your attack host with two network interfaces and insert it as a bridge between a valid client and the client's normal network. Now set your host to pass SSH traffic through the bridge to the valid client (and back out) but to intercept and generate its own NFS traffic. We will now authenticate the valid client but take NFS requests from your imposter client, and the authentication channel will stay perfectly live while you're doing this.

As far as I can tell this is a fundamental weakness of doing authentication over a side channel instead of the channel that your main communication is flowing over. If the authentication is not strongly connected with the actual real conversation, an attacker can peel the two apart and pass the authentication to a valid client while handling the real conversation itself. For full security, the authentication should be an intrinsic and inseparable part of the main communication.

(There are hacks you can try if you're stuck with separate channels, like having the client observe signs of the main protocol in action and report them back over the authentication channel. If this doesn't match the server's view of the client's activity, something's up.)

PS: I'm sure this is well known in the security and protocol design community. I'm writing it down for myself, because I want to remember the logic of this after I worked it out in my head.

tech/SidechannelAuthWeakness written at 01:04:27; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.