Live data from Hacker News

Not a bash bug

paste.lisp.org

1–10 of 189 posts

Re: Not a bash bug

#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 documented. When reading documentation about a mechanism, I expect that special magical strings which change behaviour of the mechanism are clearly documented. If such documentation had existed, someone might have noticed it and guarded against it.

> Assumedly programs like apache filter out environment variables properly. But unfortunately, in the validation of input data, they fails to validate correctly input data because they don't expect that data starting with "() {" will be interpreted by their bash child processes. 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 isn't easy to validate and control data against an unknown magical feature in one of many possible shells.

> But on the other hand, it is free software and not difficult to check the source to see as the nose in the middle of the face, what is done. When reusing a component with missing specifications and lacking documentation, checking the source of the implementation should be standard procedure, but it has clearly not been done by Apache or DHCP developers.

I think the shell is specified in POSIX/SUS. Checking the source of all possible open-source shells would be a huge job. I don't know how they should check source code of the closed-source shells. I don't blame them for using the environment variables according to available documentation.

Edit: typo

Re: Not a bash bug

#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 toxic environment variables is infinite -- are we to scan the entire PATH for each environment variable to make sure it isn't dangerous? What if the CGI script updates PATH?

There is no way to solve this problem with sanity checks. I've yet to peek at the source, but I'm told this feature is vital to implementing things like backtick operators. I think it is too dangerous however, and I don't want shellshock to become a class of bug rather than an instance of toxic environment variables. We're going to have to rip this feature out and re-implement large portions of functionality.

The author is right that this is a product of bash being written in a more trusting time. This is not the first nor the last time the 1970s security models will come back to bite us.

edit: forgot reference:

[1] http://seclists.org/oss-sec/2014/q3/741

edited to add:

Also, Apache does have a mechanism to filter out toxic environment variables; headers are added as HTTP_HEADER_NAME, because its generally the names of environment variables that allows them to be dangerous and not their content. Executing code as a result of parsing the value of an environment variable with no special meaning is a vulnerability.

Re: Not a bash bug

#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 design flaw: buffer overruns, sql injection, the openssl bug a few month back and now this. Let's go back to sanity and use well defined binary protocols where there is no damn way to send a command by text but only very explicit semantics, and stop the unix way of thinking that text should be more than a human interface. Text should never be used as a command language in between complex programs. Period.

Re: Not a bash bug

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

Re: Not a bash bug

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

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.

Re: Not a bash bug

#8
post #5

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

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.

Re: Not a bash bug

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

I really don't think making protocols less understandable by humans will solve anything.

This has always been and always will be a hard problem. Consider this quote which I found in The Shellcoder's Handbook:

"Wherever terms have a shifting meaning, independent sets of considerations are liable to become complicated together, and reasonings and results are frequently falsified." -- Ada Lovelace

We've known about this since literally the beginning; we'll be cursing ourselves over it until the very end. Vulnerabilities are going nowhere.

Re: Not a bash bug

#10
post #8
post #5

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

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…

Why is bash the only program which has special permission to trust its input?
Post reply on HN