6 ms·
The 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
by claudius 12y ago
The 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.