Live data from Hacker News

Not a bash bug

paste.lisp.org

121–130 of 189 posts

Re: Not a bash bug

#122
> The problem is that 5 years later, new software was developed (apache, dhcp, etc), that uses bash in child processes

I don't think this history is correct.

At the time, most systems used sh as the default non-interactive shell. The other shells such as csh, ksh and bash were considered to add interactive niceties, but programmers and sysadmins expected scripts to use sh.

One of the reasons sh doesn't have a lot of wiz-bang features is that it needs to stay compatible and portable across all the different Unixes so that all the scripts, past and present, will work. And sysadmins liked this conservative approach.

It wasn't until the rise of Linux, and the aliasing of /bin/sh to point to bash, that sysadmins started becoming comfortable with running bash as the default non-interactive shell. And that was only because bash promised to be fully compatible with sh. And bash was compatible but it also added new scripting features. But most developers and sysadmins rejected using these new features because you would lose portability to sh systems if you did so. That is until now, with the dominance of Linux and portability becoming less of a concern.

So really this bug is the fault of bash's embrace-and-extend strategy.

Re: Not a bash bug

#123
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 without that change, fixing this bug still preserves the case that allowing arbitrary data into the values of a whitelist of environment variables is safe.

In general, allowing modifications to a subset of the environment (and by this I mean the entire system environment, not environment variables) needs to be safe. Allowing programs to upload arbitrary data to /tmp/uploads is safe, allowing programs to upload to e.g. ~/.profile is clearly not safe.

In PJBs world it is not possible to set any environment variable to any value without reading the source code of every program that might possibly be called by any of your children. This is clearly not tenable.

Re: Not a bash bug

#124
post #61
post #57

Earlier quoted context omitted.

It's the requirement for the JSON parser, not for apache. It's like saying apache should quote SQL strings automatically so that SQL injections can't happen. This is not apache's job!

It's the job of the CGI program, which is the same code that would have responsibility for sanitizing environment variables before calling bash.

There's nothing for the CGI caller to sanitise, how could and why should it know how arbitrary programs are going to arbitrarily misinterpret what it forwards? The CGI script could be Python eval()'ing it or Ruby interpreting it as a local file to display or delete, and it's no business of the CGI caller that they do.

All the CGI caller can and should do is forward correct data as defined by RFC 3875, the rest is not its job.

> sanitizing environment variables before calling bash.

The CGI caller may not even be calling bash, then what? Should it remove anything which looks like valid PHP code because it's calling a PHP CGI? Oh but now the PHP CGI uses system() which creates a subshell which is still holed, and we end back with: if it becomes the CGI caller's job to cleanup data which could be misinterpreted by application code, the only thing it can do is stop working entirely.

Now if you want a mod_bash_is_retarded prefilter feel free to implement one, but it most definitely is not mod_cgi's job to fix that crap, mod_cgi's job is to correctly implement RFC 3875, and the number of times bash is mentioned in RFC 3875 is 0.

Re: Not a bash bug

#125

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…

The analogy is very weak, SQL injection should be prevented in your application. Does Apache need to set global environment variables, it seems pretty extreme that it just takes all the user input and makes it available to the underlying shell, there will be a whole class of bad stuff that comes from this!

> Does Apache need to set global environment variables

Apache? No. mod_cgi? Yeah, because that's its fucking job because that's how CGI works http://tools.ietf.org/html/rfc3875

Re: Not a bash bug

#126
post #40
post #24

Earlier quoted context omitted.

But without knowing how other apps treat that data, Apache can not know what needs to be done to sanitize the data. For what Apache knows, that CGI it executes could treat the presence of the letter "x" in any environment variable as "start a nuclear war". While it may make sense for Apache to sanitize the data against specific known, common problems, until this week this was not a specific known problem. It might ha…

Apache doesn't have to know how apps treat data in order to use a secure mechanism of IPC rather than passing variables set by people on the internet. Random person on the internet shouldn't be able to set shell variables. Not 'x', not anything else.

Apache will pass data via more secure means unless you explicitly use mod_cgi, which happens to have an interface that requires that the data is passed via the environment.

If you don't want random person on the internet to be able to set shell variables, either don't enable mod_cgi, or don't use CGI's written in a shell script.

Re: Not a bash bug

#127
post #88

This seems like contrarion nonsense. Therte is no sane reason for a variable definition to result in code execution. There is no sane reason for a function definition to result in (immediate) code execution. Part of those things very purpose is not to result in execution, because we have explicit syntax for asking for execution, precisely because the purpose of these constructs is not to execute. If anyone ever inten…

It is an amazingly powerful bug. In what system can you plug a magic value ("() {") into a variable which everyone expects to hold static data, and have the value of the variable interpreted as code and executed spontaneously on invocation?

And: The magic value is undocumented.

And: Any instance in the entire tree of calls will do this.

Some of this is strictly on bash. But some of it also has to do with the environment feature of Unix, which is basically a god object with all the power and temptation ("look what we could get for free if we let it be a function!") that entails.

Re: Not a bash bug

#128
post #71
post #68

Earlier quoted context omitted.

Where in the CGI spec does it say anybody has to eval anything?

Nowhere. Apache should have used a socket rather than the shell (which effectively evaluates data as instructions). People knew shell was insecure in the 90s, and there were malicious users back then too. I think environment variables were used either due to naivity or an ultimately mistaken concept of simplicity. Sunning up the entire thread: Apache should have used a socket, and should have known they needed to.

Apache doesn't have the option of using a socket for implementing the CGI spec. The spec specifies environment variables.

Apache could refuse to provide a mod_cgi, in which case it would never have gained the position it did, and some other server with support for CGI would have.

Re: Not a bash bug

#129
post #3
post #2

> This feature is documented under the -f option of the export built-in command. The implementation detail of using an environment variable whose value starts with "() {" and which may contain further commands after the function definition is not documented, but could still be considered a feature. This undocumented implementation detail is also a limitation on the use of regular environment variables, and should be…

I agree. This is an interesting idea, so I upvoted the paste. But I don't think this author knows how deeply the bug runs, either; the most recent way to exploit it is to export an environment variable of, say, ls to a bash function. [1] Usually the amount of toxic environment variables are considered to be finite; PATH, LD_PRELOAD, etc., etc. If the name of any executable on the PATH is dangerous, than the number of…

"the most recent way to exploit it is to export an environment variable of, say, ls to a bash function."

Even before the redhat patch you would need something to set echo=() { ... but how will an attacker do that when they can only set something like HTTP_USER_AGENT=() { ... ? See how overriding a builtin is not and never was a vulnerability?

Re: Not a bash bug

#130
post #119

Earlier quoted context omitted.

The point of the OP is that if a program has chosen bash to be handler of untrusted user data, then the program has made the wrong choice, because bash is clearly (hindsight!, I'm not claiming I wouldn't have made the same choice) not designed or that purpose. A handler for untrusted user data should be a program specifically designed for that purpose, which should receive the data directly. Similarly, if a Ruby or P…

So ruby and perl are specifically designed to be a handler of untrusted data? How do I know what other programs are designed for such a task? What's a "generic program"? At this day and age, it is expected that pretty much all software ought to be designed with security in mind (not that it always is). Because any piece of "generic software" (or just software) is otherwise going to be exploited. Especially on platfor…

> So ruby and perl are specifically designed to be a handler of untrusted data?

Perl actually is when used in taint mode. http://perldoc.perl.org/perlsec.html

Post reply on HN