Live data from Hacker News

Not a bash bug

paste.lisp.org

81–90 of 189 posts

Re: Not a bash bug

#81
post #67
post #59

Earlier quoted context omitted.

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

The point is that, when bash was written, there were few mechanisms for executing code as another user. There were servers/daemons, but they did not execute user code.

Of course some people would pipe to shell in their .forward file and eventually get pwnt, but it was a freshman mistake, and the damage was isolated.

Once you reach the point of executing a shell with an euid other than your own, it's not the shell's job to sanity check your actions.

The web has changed the execution model thoroughly. And people now do lazy things based on their loose understanding of flexible execution models.

This is neither a bug in bash, nor a bug in Apache, etc. It's an integration bug between two complex systems that were designed with zero-to-poor knowledge of each other.

Re: Not a bash bug

#82
post #70
post #12

Earlier quoted context omitted.

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.

In SQL injection, your SQL server behaves as advertised. If you pass it SQL code, it will execute that SQL code, so you need to be careful that you don't pass it SQL code coming from untrusted input.

With this exploit, bash is not behaving as advertised. If you pass it an environment variable with a certain value, it executes code. There is no way to sanitize your input to completely protect against this class of bug.

Re: Not a bash bug

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

Plenty of other shells support backticks without the "export -f" magic. They must, as backticks are mandated POSIX behavior; few support "export -f" at all. (And at least one that did, the old Bell Labs post-v7 "Research Unix" shell, used only environment variables with embedded characters which couldn't easily be created by normal means, to avoid the risk of "magic processing" on things like TERM and HTTP_FOO.)

Re: Not a bash bug

#84
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 should have used a socket, and should have known they needed to.

Well, there's nothing inherently dangerous about setting environment values. Yes, some have special meanings in special contexts but so could data piped over a socket.

So your argument boils down to: Apache should have seen the special treatment of data in this context, and used another context instead.

That's fine, but it doesn't address the real problem, which is that the shell was not designed to be executed on behalf of other users. There's no spec to say that data received from the "other" channel will not be interpreted or used unexpectedly.

Until you have that guarantee, you're just rearranging the problem space. There's no systemic improvement.

Re: Not a bash bug

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

You're getting close, but you missed the essence. It's not about text vs. binary. It's also not about "well-documented" vs. "ad-hoc". It's about preserving semantics.

"The Unix Way" means throwing away all semantic data - passing plain strings with no context, which are then parsed and re-parsed in an completely ad-hoc manner, usually with regexp-based shotgun parsers.

Note how SQL injections, or XSS attacks are prevented - people stopped stiching strings together and started generating proper instructions through code. User input is sanitized and driven through process that converts it from untrusted string to trusted data structure. Typing SQL queries in a semantic-aware system looks almost the same as stiching strings (thanks to SQL being flat), but now you can't possibly SQL-inject yourself.

So in general: stick to text formats or not, but whatever you do, never glue data structures using tools that work on data medium layer, that are not aware of the structure and meaning of data they are operating on. E.g. never glue strings to build SQL queries or HTML code.

Re: Not a bash bug

#86
> The problem is that it was designed 25 years ago.

It's just my imagination, but I keep picturing someone who did point out the possible security risks but was then dismissed as being too paranoid.

Re: Not a bash bug

#87
post #64

Earlier quoted context omitted.

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

How, if the protocol in question - the environment variables - has no concept of functions?

The matter is that Apache and the protocols (HTTP and environment vars) are just being used as a tunnel between the attacker and bash. They can't pass functions via another channel because they don't know what functions are. All they know is they're passing blobs of data - which any protocol would do, binary or not.

Bash happens to recognize a text value as functions, but it could just as easily recognize the magic value of an ELF binary and execute that, or any other binary format used to encode functions.

Re: Not a bash bug

#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 intended this, then they intended what is still best described as a bug... It is not as if intention is proof against being a bug! I have written bugs with full intent.

Disclaimer: I may be crabby from a busy week of mitigation. Still, I don't hold any particular ill will for the original bug. But a bug it is.

Re: Not a bash bug

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

It is impossible to sanitize your data if you don't know how the inband signalling works.

Re: Not a bash bug

#90
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 should have used a socket rather than the shell (which effectively evaluates data as instructions).

But the shell shouldn't evaluate data as instructions. This is the bug!

Apache could have used a socket and I could write a buggy endpoint which evaluates data read from that socket as instructions. Tada, same problem, same bug.

Post reply on HN