Live data from Hacker News

Not a bash bug

paste.lisp.org

161–170 of 189 posts

Re: Not a bash bug

#161

Earlier quoted context omitted.

Yeah, I hope I never have occasion to walk through an undocumented minefield, I mean collection of "features", designed by this person. I say this without animosity to bash devs. I think some blame can be shared. But putting it all on people you expect to understand under-documented behavior and "implementation details" in every possible version of every possible flavor of /bin/sh is madness.

I believe this just applies to bash, not sh?

On some systems, they are one and the same. /bin/sh is often symlinked to /bin/bash, which is making this so exploitable. /bin/sh is invoked by system(), popen(), etc., and referenced in script "shebangs" (#!/bin/sh at top), so I meant that nobody necessarily knows what "flavor" of /bin/sh they're going to get.

Re: Not a bash bug

#162

Earlier quoted context omitted.

> if Apache/dhclient wants to put things into environment variables... it absolutely should ... take into account all possible contexts Sorry if I'm picking on you too much, but I noticed this and thought of an even better counterexample. By this logic, it's Apache's job to prevent SQL injections. It should know that a single quote, in one possible context, can terminate an SQL string, popping the SQL parser into a s…

> Sorry if I'm picking on you too much Don’t worry. > By this logic, it's Apache's job to prevent SQL injections. Curiously, I’d call this an example for my position, not yours: It is not the job of the SQL server to prevent SQL injections, quite the contrary, it is the job of the calling application to ensure that the things it tells the SQL server to do are actually safe. Similarly, it is the job of Apache to ensur…

I see your point with the first bit. System A passes safely to System B, B passes safely to C, etc.

The problem, as you note, is that in order to correctly implement the CGI standard, Apache must pass the problematic data. Even if it took care to see "I'm about to pass this to bash, which might do something stupid with it, so I'll fix that", it can't know that a non-bash CGI executable is going to pass it to bash somewhere down the line.

I agree with your other conclusions. People will definitely be re-evaluating shells, CGI, and environment variables for at least a few months or so while this is fresh.

Re: Not a bash bug

#163

Earlier quoted context omitted.

Er... Well it's one way of it working, from the spec: 'meta-variable' A named parameter which carries information from the server to the script. It is not necessarily a variable in the operating system's environment, although that is the most common implementation. I suppose the authors of bash know that most of the implementations of CGI do this so they should be preventing bugs like this. Thanks for your clarificat…

Keep reading. Use of environment variables is specified for Unix. (And, actually, for all other systems which the RFC provides a specification, differing only in minor detail.) http://tools.ietf.org/html/rfc3875#section-7.2 For UNIX compatible operating systems, the following are defined: Meta-Variables Meta-variables are passed to the script in identically named environment variables. These are accessed by the C lib…

> "This is neither a bug in bash, nor a bug in Apache, etc. It's an integration bug between two complex systems that were designed with zero-to-poor knowledge of each other."

Which makes OP's comparison to Ariane 5, a spacecraft with an infamous bug that could be described as an "integration bug" (between older and newer parts of the software), even funnier. Hopefully the development teams of a rocket were a bit more in-sync than those of Apache, bash, distribution maintainers (some of whom have made /bin/sh link to bash), and CGI programmers.

Re: Not a bash bug

#164

It took a lot of discussions with pjb on irc for me to decide he is not actually a troll. His is very literal. The part where assigning a particular variable to any environment variable causes arbitrary code execution is a bug. The part where you can define functions by setting environment variables is a feature. It would be far better if the variable names needed a prefix (e.g. BASH_FN_foo='() {...}')., but even wit…

If an environmental variable is like a file, this bug is like automatically executing code stored anywhere in the filesystem if the file happens to certain a magic number. Using a prefix (if documented) is like looking in a certain directory. It should have been obvious that scanning ALL environment variables is a bad idea, if not for security than for correctness, because interpreting data belonging to another progr…

agreed

Re: Not a bash bug

#165

Earlier quoted context omitted.

But the problem with Shellshock isn't random environment variables. It's random environment variable VALUES in well-defined environment variable names. It's pretty well-known that there are certain dangerous environment variables (like PATH, LD_PRELOAD) that should not be blindly set. But CGI only sets CGI environment variables like PATH_INFO, as well as HTTP_ . That even these can be dangerous because bash executes…

Is this really a loose typing issue: we give Bash data that should be of type "display text" (a sub-type of string I suppose) and it treats that data as type "executable command" (also a sub-type of string). Would it be possible to wrap|tag input to bash so that only when a program|script sets the env variable with string that's typed as "executable" does bash even think of exec-ing it. I guess that removes some of t…

The issue is that the environment isn't a bash-specific thing. Anything can and regularly does set environment variables, and there's no space in there to set a flag for "this is executable" - if it's in the value, anything can set that flag, and the problem here is triggered by programs setting environment variables from external data.

Re: Not a bash bug

#166
post #81
post #67

Earlier quoted context omitted.

Ahem. Every web server passes "unsanitized user input" to "Turing complete systems". You have a right to expect certain things from subsystems regardless of their "Turning completeness". * A file system should store your bytes, though nothing prevents a file system written in C from executing, say, logged HTTP requests as commands. * A CGI script should sanitize form data, though nothing prevents a PHP script from bl…

The point is that, when bash was written, there were few mechanisms for executing code as another user. There were servers/daemons, but they did not execute user code. Of course some people would pipe to shell in their .forward file and eventually get pwnt, but it was a freshman mistake, and the damage was isolated. Once you reach the point of executing a shell with an euid other than your own, it's not the shell's j…

I'm not quite so sure about that. One of the early examples I've seen of Unix use (I think Ken Thompson was actually in the video, from early 80's) showed using the various tools to process file data that got downloaded from somewhere else (where that data was supposedly created by another user). So if you had a script that did:

    cat downloaded_file.txt |\
    while read inputline
    do
        #some processing
        #call another shell program
    done
In this case, bash would still be vulnerable even without the Internet involved -- just processing a data file you got from Bob in Accounting.

Re: Not a bash bug

#167
post #118

Earlier quoted context omitted.

And it's not limited to C. E.g. I would be in favor to remove os.system from Python (in favor of subprocess.call). The `-syntax (backtick-syntax) in Ruby is particularly evil. It's so convenient because it is so concise, but I guarantee you that it is the source of a lot of vulnerabilities. It should be removed ASAP. I think that's kind of a theme in Ruby: is it convenient? Then put it in. But I would have expected m…

subprocess.call is also vulnerable to this, though. It calls out to bash.

I believe you would need to explicitly pass shell=True for that though.

Re: Not a bash bug

#168
post #31

Earlier quoted context omitted.

You are describing the problem exactly: it all too tempting to pass text around from user input to command line arguments without any way to validate the text data and assume it's ok because it's easy. It's exactly the same arguments that goes in between static and dynamic typing in programming languages: static typing ensures some sort of semantics is respected. If you pass text around, because it's easy and fast, m…

If the protocol was binary there is no way in hell you would be tempted to pass it's data without validation to an external program because you'd have to respect the API and because there would be not way to just send a bunch of commands I assume you're talking about Apache - but Apache had no way of validating the data. The protocol just said "this is a blob from the client", which any binary protocol for the task m…

no, the problem is that you can treat any kind of text data as an executable. You can try to fix this by adding mountains of complexities and excuses but would still be true: as soon as you have text enter the equation you need to escape/encode/decode and parse. Every time you do that you add more complexity than is needed, and also you add many ways to abuse the programs and create "interesting bugs".

Re: Not a bash bug

#169
post #63

Earlier quoted context omitted.

There are two things to differentiate, in my oppinion. In most cases, the shell is just used to find programs in the PATH when a C programmer uses system(). And for that case, which is probably 99% of the time when /bin/sh is being invoked, it would make perfect sense to implement this with something that exhibits less attack surface. Taking the "dhcp-exploit" as an example (set a DHCP option on your server to "(){..…

> when a C programmer uses system() I said it in another thread but this is almost always a mistake. The execve family is much less ambiguous about what gets passed to the program. Using it avoids this type of bug by not putting the shell where it doesn't need to be.

Yes, it isn't that hard to use exec*() to execute a single program, but it gets rather messy if you want to execute a series of piped commands.

Also another function to worry about is popen().

Re: Not a bash bug

#170
post #148
post #76

Earlier quoted context omitted.

There's a lot of Apache hate here but I have to wonder if you've actually used it. Anyone stuck running cgi stuff with apache invariably goes to fastcgi or mod_fcgid for performance reasons, which already uses a unix domain socket. That shellshock exploits will still be possible in this configuration is once again, not Apache's problem.

Pointing out that people from the internet shouldn't be able to set shell variables isn't 'hate' - it's basic security and knowledge that alternative, more secure transport systems exist. Saying that Apache (and other apps) passing data from random people on the internet to a known insecure environment like a shell, that was known to be insecure in the 90s, is 'not Apache's problem' doesn't actually absolve Apache of…

1) Since the mid-90s Apache and similar http servers have offered fastcgi as a way of communicating with processes with sockets. So you can understand why hearing you single out apache to "use a more secure IPC like sockets" detracts from the main argument which I'd otherwise agree with.

2) I'd wager that the people who came up with CGI initially had expected that the process apache spawns would be anything but a shell.

3) Non-shell CGI processes happily deal with all manner of binary, back-ticks, dollar signs etc. in their HTTP_ envars all day and have done so for nearly 20 years. It's not a huge leap in logic then that these envars should be considered capable of holding arbitrary data without exploding.

4) You make it sound like nobody has considered environment variables a problem before, but sanitizing the environment before spawning a process from the CGI was already a well-established best-practice way before this bug came along. That process looks like - whitelist of envar names, remove all others; check PATH/LD_LIBRARY_PATH/etc sanity; command string parameters use specialized token substitution (eg. "echo %{integer}%" where some bespoke code throws an error if %{integer}% is interpolated to anything other than an integer), etc.

5) Despite the insanity of running CGI stuff which I would generally agree isn't a great idea, I'm pretty sure I'm allowed to be surprised that the mere content of an environment variable, whose job it is is to contain arbitrary data to be passed on to the CGI app should cause things to explode.

Post reply on HN