7 ms·
> If there's a bug, it's not in bash, but in apache and the other internet facing programs that call bash without properly validating and controlling the data t
by myhf 12y ago
> If there's a bug, it's not in bash, but in apache and the
other internet facing programs that call bash without properly
validating and controlling the data they pass to bash.
It's absurd to think that a transport layer should be responsible for "validating" all possible contexts in which the data it transports could be used. How is apache supposed to know the difference between using a magic string and simply mentioning it? How is apache supposed to know what magic strings apply to all possible subprocesses of sh that inherit environment variables? A program that receives user data has to be responsible for validating that data, and it's not productive to characterize the lack of validation as a "feature" just because it can be used to provide functionality.
This kind of misguided thinking leads to practices like mod_security refusing to allow comments that contain the magic strings "1=1" because they might be trying to inject SQL into something.
- claudius 12y agoThe point here is that Bash was not designed to receive untrusted user data in environment variables. On the other hand, Apache/dhclient was designed to receive untrusted data, but then handed that over to someone which did not expect untrusted data without validation. In other words, if Apache/dhclient wants to put things into environment variables, it absolutely should make sure to do this properly and indeed to take into account all possible contexts.
- fabulist 12y agoWhy is bash the only program which has special permission to trust its input?
- myhf 12y agoI guess as a POSIX-compliant shell, Bash can be expected to trust its inputs on stdin and in special environment variables like PATH. But the problem emerges from trusting 100% of inputs, not just the inputs that are intended to be trusted.
- tomjen3 12y agoIt has permission to trust the input the user enters into it, because that is its job. 20 years ago nobody assumed variable environments were an issue, but this should have been fixed years ago. I am also pissed that they patched the parser, the feature is still in there when nobody uses it and it has already proven to be a security vuln once.
- fabulist 12y agoIts used by bash itself for communicating with subprocesses. Input you type at the terminal is not the same as an environment variable; hackers set environment variables much more often than legitimate users.
- vidarh 12y agoThere are many other ways Bash could do that, though, which would make it much harder for further exploits. Such as opening a pipe and writing them to the sub-process that way so it goes "out of band" from the regular environment variables. Or if it has to be in environment variables: Accept a special argument in the argument list that is a key it uses to sign the variables. It does not need to remain secret - just make sure that just inheriting environment variables with potential attempted exploits is insufficient for anything to get executed. And/or change the way these definitions are handled - I get that it's tantalizingly simple to just pass this through their usual parser since then you get the function definition parsing for free, but at the very least this parsing of the environment variables shouldn't go through a code path that even potentially executes anything.
- masklinn 12y ago> There are many other ways Bash could do that, though KSH and ZSH will load functions from files they find via $FPATH.
- vidarh 12y agoApache does not in general know whether or not data will be passed to bash. And they can't take into account all possible contexts, because that would involve reading the mind of all possible future users of the interfaces they provide, to make sure none of them decides to call out to programs that treats previously inert data as code.
- nailer 12y agoApache knows what data Apache passes it its own sub processes, which is the issue here. Nobody is expecting Apache to sanitise other apps, just itself.
- vidarh 12y agoBut 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 have been if the Apache team audited the code of every plausible piece of code that people might use to interpret CGI scripts, but that's not a realistic scenario.
- nailer 12y agoApache 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.
- anon1385 12y agoIf you can't put data into variables then that makes what you can do with shell scripts quite limited. Your advice is really: don't use shell scripts any where near untrusted data. Tracking which data is trusted and which isn't across different processes in different languages across different systems is not a trivial task. So really the advice is: don't use shell scripts. That's sound advice, but not something Apache can or should enforce.
- scintill76 12y agoSo if I write a new shell called rash, that executes anything in an env var between, say, backticks, and install it as /bin/sh, it's Apache's job to neutralize backticks in untrusted data? I can agree with some of the things you say, but this seems to be the logical conclusion, and it's crazy. The most consistent moral I'm deriving here, is that shells are for executing arbitrary commands in a flexible environment, so don't even touch them if that's not what you want. This applies to Apache, CGI wrappers, any other kind of web development.
- danielweber 12y agoinstall it as /bin/sh, At first glance, I think that's your problem. Fundamentally, though, you can't always point to "it's this one component that is broken." There is the classic example that was used to criticize Authenticode, which was Microsoft's way of dealing with mobile code back in the 1990's. It said "all the code is signed, so if something breaks, you know who to sue." Well, imagine two programs: 1. One of them formats your hard drive, and on installation puts itself into your Quick Start list. 2. One of them runs every single program in your Quick Start list at start up. Which piece of code is responsible for formatting your hard drive?
- scintill76 12y agoIt does indeed seem wrong to put magical behavior into /bin/sh, but that's exactly what's going on in this bug. bash is often installed as /bin/sh and is doing extra, non-standard, sparsely-documented behavior. I don't know that it really violates POSIX et al, but it definitely goes on the list of factors at fault. And yes, I agree it's difficult to assign blame.
- nitrogen 12y agoBecause of popen(), it's near impossible to know which binary programs might unwittingly invoke a shell.
- scintill76 12y agopopen() is documented as using the shell, so I wouldn't use it if I follow my moral of the story above. Maybe you're referring to the "shebang" (#!/bin/sh), whereby any executable, that you may have invoked without a shell, can signal that a shell should interpret it? I guess you have to strip down the environment to only the things you need to know. That's unfortunate, because the nice thing about the environment is that it's inherited, so the user can put in configuration that's needed 3 or 4 steps down the line from where it originated.
- anon1385 12y agoYou say dhclient should take into account all possible contexts before passing data to bash, but it's not easy to know what data shells will parse as code and what they won't[1]. If we have to sanitise data before passing it to shells then the only sane conclusion is to never pass untrusted data to shell scripts. I certainly don't trust myself to know the full range of features in all shells that might suddenly turn a plain text string into executed code. I can't think of any other people that I would trust to know that either. Is that really what you are advocating here? Don't ever use shell scripts with untrusted data? That has been my philosophy for a long time, but up till now that position has been viewed as extreme by most people I've shared it with. [1] there are still exploitable bash parser issues to be revealed http://seclists.org/oss-sec/2014/q3/777 http://seclists.org/oss-sec/2014/q3/777
- nitrogen 12y agoUnfortunately the specs for system() and popen() require the use of shells. It was known that you had to escape arguments and control the names of environment variables, but it's entirely bizarre to expect people to know before shellshock that the values of otherwise completely safe and sanitized variables might still be interpreted by bash as code. We shouldn't have to give up popen() just because bash was designed insecurely; we should fix or replace bash.
- scintill76 12y ago> 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 state that allows for arbitrary statement injection. It also needs to know about any other database language that could ever possibly be invented, now and for eternity, because we can't know how long any given version of Apache will remain in use.
- andy_ppp 12y agoThe 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!
- masklinn 12y ago> 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 http://tools.ietf.org/html/rfc3875
- andy_ppp 12y agoEr... 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 clarification. I still maintain that this sounds like a very insecure mechanism for passing information from Apache to your application.
- 12y ago
- vidarh 12y agoApache has no control over what application code it is that receives the evironment variables via mod_cgi, and most of the time it will not be bash, but indeed a special purpose application or script interpreter that is designed to receive untrusted user data in environment variables since that is what the CGI spec dictates. That sometimes people opted to use bash as the script interpreter and/or that people sometimes shell out to bash from within other environment without sanitizing the environment they pass along, is not Apache's fault.
- regularfry 12y agoBasically what they're saying is that CGI should never have happened.
- anon1385 12y agoIt goes far beyond CGI. Linux systems use shell scripts all over the place where the data involved may come from untrusted sources. DHCP is one example, but there are many others. If shells can't be trusted not to suddenly execute the data inside variables then shells can't be trusted to do anything.
- vidarh 12y agoWhile that might have been great, the alternative is: People should not have used shells as CGI handlers, and people should (irrespective of CGI) sanitize any environments passed on when spawning other programs from their applications. This latter is really something we should do irrespective of where the input is coming from. Even if the content comes from trusted sources, passing the environment unchanged to sub-processes means we risk all kinds of unintended consequences if an application developers decides to spawn a sub-process that exec's into some process that makes decisions on various variables. It's a bit like letting our applications call functions with random junk in the argument list.
- regularfry 12y agoOne thing I've learnt over the years: anything which relies on "people should..." as a basis is doomed.