Live data from Hacker News

Not a bash bug

paste.lisp.org

61–70 of 189 posts

Re: Not a bash bug

#61
post #57
post #46

Earlier quoted context omitted.

Your comparison doesn't make any sense. It's an obvious requirement for a JSON parser that it be able to parse input from arbitrary sources, including malicious ones. It's not so obvious that a shell should have to deal with malicious environment variables, due to the reasons outlined in the original post.

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.

Re: Not a bash bug

#62
I agree with the OP. Bash is a scripting language. If you use it, you must be aware that you can damage the system. If you allow your script to get input from the untrusted sources it's your job to sanitize it.

Re: Not a bash bug

#63
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 with all your points. I think the real bug is that all this stuff calls out to a shell at all. Sure, it's convenient, but it's basically eval().

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 "(){...}; exploit;"), I think it's less clear: Implementing the functionality of updating configuration files according to the DHCP options sent is a prefecty reasonable place to use a script written in sh/ksh/bash! It's easy to implement by any sysadmin, works very reliably with a little care, and performance-wise it's not critical at all.

And regardless of the language you implement it: There's some place where user-input has to be sanitized, but up to now, it was considered common knowledge that arbitrary data in an environment variable is safe as long as the variables' name adheres to some convention (prefix them all with PROGNAME_...). And bash doesn't respect this convention by looking at variable CONTENT, even though I'm pretty sure that it was already established when the bash-project started... (see, for example, handling of "special" variables like LD_xxx in suid programs or the dynamic linker)

Re: Not a bash bug

#64
post #4

It's an "internet tech" bug. Every developper should know how hard it is to parse textual data vs well defined binary in a secure and fool proof way. Yet every damn internet piece of infrastructure is based on handling textual data, mash it up, pass it around, escape and unescape it in hundreds of stupid formats. No wonder that most security troubles surfacing over the years are some form of abuse of this crazy desig…

Please describe specifically how would that have helped. This has nothing to do with parsing text. The problem here is that Apache et all send untrusted data to a process that treats it as code. It wouldn't matter if HTTP was a binary protocol and if bash read a well defined bytecode instead. I mean, look at shellcodes.

If the protocol was binary, exporting variables to subprocesses and exporting functions to subprocesses would go in different places, and Apache would know to send the one but not the other

Re: Not a bash bug

#65
post #56
post #40

Earlier quoted context omitted.

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.

Your response sounds like blaming the world's oldest webserver for being the world's oldest webserver. CGI sucks, but telling the 1990s to go home and not come back until it has a secure mechanism of IPC just isn't helpful: this seriously isn't an Apache (or other CGI httpd) problem. As someone else said, traditionally only the names of shell variables have mattered, not the content. Apache exports most of its envars…

Unix domain sockets existed in the 90s and would have done the job adequately without evaling anything in transit.

Apache transmitting data created by random people to CGI processes using environment variables is most definitely Apaches fault. It was a dumb idea in the 90s and it's a dumb idea now.

Re: Not a bash bug

#66
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…

> 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.

If you can set arbitrary environment variables, you're pwned and have always been pwned. You can set all manner of interesting things, including LD_PRELOAD, to control the execution environment and potentially execute arbitrary code.

EDIT: Putting random data in an environment variable where you pick the name should always be secure, though, which is an assumption that most of *nix makes.

Re: Not a bash bug

#67
post #59
post #55

Earlier quoted context omitted.

"Quite humorous"? * In Unix, shell scripts and shell subprocesses are everywhere, and are supposed to be everywhere. * Environment variables are passed across subprocesses by default, you need to explicitly filter the environment to prevent that. Therefore, if you write a shell, the reasonable assumption is that it's going to be integrated into pretty much all "systems"/programs running on a Unix box with this shell,…

Since the sub-process runs as the same user as the original process, it wasn't really considered a security problem. The problem is calling a sub-shell without sanitizing the environment first. It's really a bad idea to connect unsanitized user input to a turing-complete system of any kind.

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 blithely shoving unsanitized data into SQL queries.

* And a shell should pass environment variables to subprocesses, though nothing prevents it from interpreting variable values (or names, or a combination of names, values and the time of day) as commands.

As I said - I don't think it's a security bug in bash, just another one of endless misfeatures. It's about as crazy to interpret environment variable values as code because they have a special-cased form as it would be to interpret, say, file names as code, or certain byte sequences passed to the write() system call as code, etc.

Re: Not a bash bug

#68
post #65
post #56

Earlier quoted context omitted.

Your response sounds like blaming the world's oldest webserver for being the world's oldest webserver. CGI sucks, but telling the 1990s to go home and not come back until it has a secure mechanism of IPC just isn't helpful: this seriously isn't an Apache (or other CGI httpd) problem. As someone else said, traditionally only the names of shell variables have mattered, not the content. Apache exports most of its envars…

Unix domain sockets existed in the 90s and would have done the job adequately without evaling anything in transit. Apache transmitting data created by random people to CGI processes using environment variables is most definitely Apaches fault. It was a dumb idea in the 90s and it's a dumb idea now.

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

Re: Not a bash bug

#69
post #40

Earlier quoted context omitted.

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.

If 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 Apach…

Yes. Don't use shell for data transmission. Use a socket. Apache had that choice, knew bash was insecure (as everyone did in the 90s, that's why across can't be setuid), and didn't exercise the right option.

Re: Not a bash bug

#70
post #12
post #8

Earlier quoted context omitted.

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 ta…

Apache 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.

How is this any different from SQL injection? Input from the world must be sanitized. All we're doing is increasing the scope of the word input - ALL input from the world must be sanitized.
Post reply on HN