11 ms·
Not a bash bug
- ahy1 12y ago> 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
- fabulist 12y agoI 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 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.
- vertex-four 12y ago> 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.
- FooBarWidget 12y agoBut the problem with Shellshock isn't random environment variables. It's random environment variable VALUES in well-defined environment variable names. It's pretty well-known that there are certain dangerous environment variables (like PATH, LD_PRELOAD) that should not be blindly set. But CGI only sets CGI environment variables like PATH_INFO, as well as HTTP_. That even these can be dangerous because bash executes code on any* environment variable, is completely unexpected.
- pbhjpbhj 12y agoIs this really a loose typing issue: we give Bash data that should be of type "display text" (a sub-type of string I suppose) and it treats that data as type "executable command" (also a sub-type of string). Would it be possible to wrap|tag input to bash so that only when a program|script sets the env variable with string that's typed as "executable" does bash even think of exec-ing it. I guess that removes some of the hack-ability and would need major rewriting of bash. I'm a layman trying to do CS ... what could possibly go wrong!
- vertex-four 12y agoThe issue is that the environment isn't a bash-specific thing. Anything can and regularly does set environment variables, and there's no space in there to set a flag for "this is executable" - if it's in the value, anything can set that flag, and the problem here is triggered by programs setting environment variables from external data.
- scintill76 12y agoYeah, 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.
- kcbanner 12y agoI believe this just applies to bash, not sh?
- scintill76 12y agoOn some systems, they are one and the same. /bin/sh is often symlinked to /bin/bash, which is making this so exploitable. /bin/sh is invoked by system(), popen(), etc., and referenced in script "shebangs" (#!/bin/sh at top), so I meant that nobody necessarily knows what "flavor" of /bin/sh they're going to get.
- nailer 12y agoThere are other methods of IPC other than shell variables. The shell is a known insecure environment, which is where there are limits on setuid for shell scripts. By letting everyone on the Internet set shall variables Apache and whatever DHCPd (ISC?) did something they could have known would have bad consequences whether this feature/bug existed or not. The only data Apache needs to control is Apaches.
- icebraining 12y agoFrom what I understand, Apache doesn't send them to bash. It sends the to whatever binary is configured to handle the request (using CGI), which were then calling bash unbeknown to Apache (but implicitly passing the same environment variables).
- ygra 12y agoLots of functions to start another process start a shell instead and is a command line to be executed, e.g. system or popen. The convenience in that case is that you don't need your own handling of $PATH or wildcards or argument parsing. It's pretty standard on UNIXoid systems.
- asveikau 12y ago> The convenience in that case is that you don't need your own handling of $PATH You don't with execvp or execlp either. > or wildcards or argument parsing. IMO this is of dubious value from, say, a C program. Why "parse" the args? Just generate a list...
- danielparks 12y agoI 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().
- philh 12y agoHow is it different to set some environment variables and then call out to a shell script, versus to set some environment variables and then call out to a perl script, or a binary compiled from C?
- TeMPOraL 12y agoIt's not. It's the "calling out" part that is wrong. You should never call out to anything by passing untrusted user input directly. Any information that came from the outside must be explicitly passed as data through proper serialization mechanisms. For instance, you don't piece your SQL queries by concatenating strings. You use an abstraction layers, in which you code the query structure and you pass user input as data. There is this extra step of saying "this is data, not code" that strips the external input from executability. (for the same reasons, if your templating engine is just concatenating strings and not building the page out of trees, you're doing it wrong, but it's a topic for another day) It's a problem you get when you believe in "the Unix way" a bit too much. Yes, everything is text, but no, not everything has the same semantics.
- philh 12y ago> You should never call out to anything by passing untrusted user input directly. So if I call a CGI script with parameters foo=bar, what data should apache pass to the handler, if not something along the lines of the string "foo=bar"? When I pass the header "User-Agent: baz" and the handler asks for the user-agent, what should it be told if not "baz"? Environment variables are data, not code. When apache executes a cgi script, whether it's C or perl or shell, it makes the user input available as data in defined locations. There's a bug in bash which causes some of that data to be executed, but there's no way to protect against that class of bug. This isn't a case of "you should have protected against sql injection attacks". It's a case of: there is a bug in your sql server, such that the query "select from Users where username='rm -rf /'" will execute "rm -rf /"*.
- meelooo 12y agoIt'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.
- fabulist 12y agoI 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.
- meelooo 12y agoIt's not about making protocols less understandable by humain, it's about recognising that we are programming computers, not humans and that it's time we accept that there should certainly be a way for the humans to interact with the program at some point we should not force the same kind of interactions on the programs themselves. It's much harder to make text and text based commands' parsing and handling secure than it is to use binary protocols in the first place.
- fabulist 12y agoI just disagree. You seem to be saying we should use binary protocols and load them directly into memory Cap'n Proto style. But what if I'm little endian and you're big endian? Parsing happens. Text-based protocols fit well into human's heads, and its the humans that have to do the debugging. I think it would only make the process of finding bugs slower and more complex, and give advantage to the attackers.
- 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.
- senko 12y agoThe bug may be bash's, but it's the entire chain that makes it a serious one: http://senko.net/shellshock http://senko.net/shellshock
- 1wd 12y agoUndocumented feature = bug.
- INTPenis 12y agoAll the programs at risk here should really be using rbash.
- 0x0 12y agoStill sounds like a bug in bash to me. What if I have a printer called "() { :;}; echo lol", so I manually export PRINTER="() { :;}; echo lol" (see http://www.tldp.org/HOWTO/Printing-Usage-HOWTO-4.html http://www.tldp.org/HOWTO/Printing-Usage-HOWTO-4.html) I don't think this was the intended behavior even 25 years ago. :)
- xioxox 12y agoThe saner way to implement this bash feature would be to have a single environment variable containing inherited shell functions. A special prefix is an alternative, but a bit harder to filter.
- sandstrom 12y agoUsing Nginx, how could one filter/drop/reject http requests where a http header start with "() {"? I know patching `bash` is most important (and I have). But it would give some extra comfort.
- saurik 12y agoThe original author of bash (a friend of mine, which is why I have this context) has been being interviewed by various newspapers today regarding shellshock, and finds the idea that he might have anticipated the number of ways people integrated bash into various systems (such as with Apache allowing remote control over environment variables when running software in security domains designed to protect against unknown malicious users) quite humorous. Apparently, it has been an uphill battle to explain that this was all coded so long ago that even by the time he had already passed the project on to a new developer (after having maintained it for quite a while himself) the World Wide Web still wasn't a thing, and only maybe gopher (maybe) had been deployed: that this was even before the Morris worm happened... > In an interview Thursday, Mr. Fox, the Bash inventor, joked that his first reaction to the Shellshock discovery was, “Aha, my plan worked.” http://mobile.nytimes.com/2014/09/26/technology/security-experts-expect-shellshock-software-bug-to-be-significant.html http://mobile.nytimes.com/2014/09/26/technology/security-exp...
- _yosefk 12y ago"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, and environment variables will travel from everywhere to everywhere. Of course the feature isn't a "bash security bug"; it's just one of those endless poorly documented, weird special cases which together make up what we know as "Unix". And the answer to anyone shooting themselves in the foot, whether it's one person or a billion, is "you should have read the documentation" - and now, apparently, "you should have read the source". It's a good thing this kind of "design philosophy" is absent outside the field of computer programming. Generally the vendor should be the extremely diligent party, and the user is assumed to be reasonably naive - even if the user is a professional (think power tools, etc.) It is only programmers, for some reason, who think that it's perfectly fine to add whatever features they want to their code without much worrying about consequences, and leaving the worrying to the users.
- masklinn 12y ago> 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. Bullshit, this may well be perfectly valid data and web servers are not in the business of shielding shells against their own misfeatures. And if they were where would they stop? It would require that webservers do arbitrary context-sensitive data analysis of everything doing through in case this is a malformed JSON string triggering a bug in GSON while that is data injected unescaped into an SQL variable and the other one's too big for an underlying C buffer. You can only end up with a webserver refusing to do anything, because some idiotic application somewhere may misuse or misunderstand anything it lets through.
- deleted 12y ago[deleted]
- avar 12y agoYour 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.
- masklinn 12y agoExcept the JSON parser may be using specially-formatted input[0] as parsing directives[1], the XML library has various custom directives and is probably sensitive to billion laugh attacks anyway, the SQL library doesn't correctly handle part of the DB's dialect, etc… in the same way you've got a shell somebody decided should smuggle code from ENVvars and didn't realise it was implicitly executed OOTB as cherry on the cake. > 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. Which I don't care for, my point is that the webserver can not wipe the ass of every bug or misfeature implemented by the shit put behind it. It's just not possible. [0] e.g. "magic" object keys or keysets, most libraries expose ways to hook into object deserialisation to do exactly that but they could do it by default as well, and I'm sure there are some which do [1] which is exactly what bash does here
- mc_hammer 12y agoofc its not a bug its a security vulnerability. Where hes wrong is having an undocumented unnamed unknown function that has eval abilities is plain idiotic; who cares if its a bug?
- mariusz79 12y agoI 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.
- clarry 12y ago> If you allow your script to get input from the untrusted sources This wasn't the problem. The problem wasn't with scripts getting untrusted input. The problem was with bash getting untrusted input -- input that isn't supposed to be evalled in the first place.
- codeskyblue 12y agoEven through bash is open sourced, But the author of dhcp or apache can't spare many time to see bash source code. It's not a bash problem and not dhcp problem. Just because every code got a some bug hiddened.
- giancarlostoro 12y agoSo basically "this code has no bugs, just undocumented features".
- codeskyblue 12y agoEven through bash is open sourced, But the author of dhcp or apache can't spare many time to see bash source code. It's not a bash problem and not dhcp problem. Just because every code got a some bug hiddened.
- xiaq 12y ago> 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.
- jerf 12y agoThis 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.
- mturmon 12y agoIt is an amazingly powerful bug. In what system can you plug a magic value ("() {") into a variable which everyone expects to hold static data, and have the value of the variable interpreted as code and executed spontaneously on invocation? And: The magic value is undocumented. And: Any instance in the entire tree of calls will do this. Some of this is strictly on bash. But some of it also has to do with the environment feature of Unix, which is basically a god object with all the power and temptation ("look what we could get for free if we let it be a function!") that entails.
- lutusp 12y ago> I would argue that the bash security concern is not a bug. It is clearly a feature. Admittedly, a misguided and misimplemented feature, but still a feature .... The problem is that it was designed 25 years ago. Apache didn't exist yet for five years! The linked article's premise requires that the bug/feature be present when Bash was first written, not be the result of more recent changes, a a time when the risks were obvious. I can't show this, but I doubt it.
- informatimago 12y agoYes, this part of the code is basically unchanged in all versions from the oldest I could get (1.14.7). What made me look for it, was a suspicion that it was some backdoor added more recently. But apparently no, it's a feature that always existed in bash (granted, an ill-advised and ill-implemented undocumented feature, but still).
- drvdevd 12y agoI think you cannot really say who has the bug in this case, from this point of view. The problem is that in order to blame one component (e.g. Apache) over another like bash, you would have to have a "rigorous" spec of the entire stack -- from network drivers to user facing programs, in order to say either "this is doing something unspecified" or is flat out wrong. This may be possible, but it also goes somewhat against the UNIX philosophy with which all of this was built in the first place.
- mcguire 12y agoThis was my initial opinion of the bug, as well. The parent processes are in control of the environment and should be validating input. On the other hand, after thinking about it, there are a number of reasons why I decided that this is at best a misfeature of Bash. It is incredibly undocumented. I've been a Unix guy for over 25 years, and I've been using Bash for most of that time. (Sorry, David Korn.) I've used Bash a lot. But I've never heard of this thing. It violates some ill-defined, personal, un-thought-about assumptions about environment variables. An environment variable with executable code? That's as terrifying as LD_LIBRARY_PATH, and that is very well known. One reason I've probably missed this feature is that it is something I would never consider using. In my opinion, it's almost impossible to secure this on the parent process' side. Sure, the parent can look for magic Bash strings, but.... This isn't just Apache, it's potentially every other network accessible program that calls a shell, and that is a very common thing to do in Unix. Finally, consider some of the special behavior of execlp and execvp: "If the header of a file isn't recognized (the attempted execve(2) failed with the error ENOEXEC), these functions will execute the shell (/bin/sh) with the path of the file as its first argument. (If this attempt fails, no further searching is done.)" You could end up starting a shell without knowing.
- userbinator 12y agoThe 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. If this is considered an "implementation detail", then I'm even more convinced that the whole idea of hiding implementation details, and thus these surprising (mis-)features, is fundamentally flawed. 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. There is absolutely nowhere in the official bash manual that mentions the special behaviour of environment variables with values starting with '() {', not even in the "differences from POSIX/Bourne Shell" list, so the natural expectation is that any sequence of bytes not containing the 0 byte (since this is a C interface) can be put into the contents of an environment variable. On the other hand it does have an extensive list of reserved variable names which have special meaning. To quote the POSIX spec on environment variables (emphasis mine) - http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_... : The values that the environment variables may be assigned are NOT RESTRICTED except that they are considered to end with a null byte and the total space used to store the environment and the arguments to the process is limited to {ARG_MAX} bytes. Thus the reasonable expectation is that Bash behaves according to the POSIX spec; it's even mentioned in http://www.gnu.org/software/bash/manual/bash.html#Major-Differences-From-The-Bourne-Shell http://www.gnu.org/software/bash/manual/bash.html#Major-Diff... that "Bash is POSIX-conformant." The fact that the function used to evaluate imported function definitions was named parse_and_execute(), and is basically the same function that executes regular commands at the prompt, was what stood out to me the most upon hearing of this behaviour although in retrospect, it wasn't all that surprising. This is a bug that, by any other name, would be just as disturbing.
- julie1 12y agoSo an ENV is a dict string => string with this feature we have a dict that point to functions. Basically it is an object. It could even has been used for passing structured data with their own functional compiler. Or objects with stateless (lambda) functions/methods usable for parallel computing. Oh fuck, this feature is a wonderfull feature in a controled environment for passing objects/code over a simple octet stream. With safe computer paradigm. We could have done RPC easily with xinetd + and shell scripts. With PAM we could have even be able to use kerberos to control the security... I could have done lots of things... I still can ... Bash I still hate you for not documenting this, and more YOU Advanced Bash Scripting guide for being so awesome and missing that. ABS you failed me. http://www.tldp.org/LDP/abs/html/functions.html http://www.tldp.org/LDP/abs/html/functions.html
- panzi 12y agoI don't agree. bash is meant to be a sh replacement, compatible with sh. So any correct use of sh has to give the exact same result under bash. bash should only extend sh in a way where the bash script would be an error under sh. bash might not be intended to be that way, but it is assumed by developers to be that way, which means it has to be that way (or it can never be used as system shell).
- putzdown 12y agoFalse premise: "Unintentional failure is not a failure." Lack of intention for a failure certainly weakens the ethical culpability of the action, but it doesn't weaken the technical or pragmatic severity of the failure. What's the point in saying the bash failure isn't a bug. It's an unwanted behavior. What else is a bug?
- wahsd 12y ago"Security in internet software and protocols were often just not considered at all in that time..." I find that a rather perplexing issue with many, especially software based products and research. How do you, in early, usually time, effort, support, and resource constrained stages of a project or research discover and identify all dependencies and requirements to the best of your knowledge so that there is not a type of runaway train effect where momentum is gained and speed is accumulated but it is frequently overlooked that there are all kinds of things like security, anonymity, etc. that are not being considered even though they will invariably become monumentally important. Take the internet today in general as a huge example of that issue; it was never developed with anonymity or privacy or security in mind and here ware are, horrified of even just the tip of the iceberg that was revealed through Manning and Snowden. If the early researchers and engineers had built the early technologies with fundamental, most basic human considerations in mind we might not be looking down the barrel of a dystopian dawn. So my question is whether anyone is aware of a method, procedures, techniques, etc. to plan for such a paradox?
- informatimago 12y agoIf you look at early RFCs, you will see that if they mention security considerations at all, it's often just to mention that they haven't been addressed at all. Specifically, the literal string "Security issues are not discussed in this memo.' is found 568 times in the 3000 first RFCs. (6 times in the RFCs from 3000 to 5887). When searchers were inventing the internet, they just put aside security considerations. In a way, security was enforced at the boundary, by universities controlling their teachers and students who could use it. When the internet becomes a public network, where anybody can send packets on it, of course security considerations become a priority, but the protocols weren't designed for security. Like IPv6, we'd need to design a new set of protocols for this public internet, taking into account security considerations as a priority. But given the speed with which IPv6 is adopted, you can guess with what readiness a new set of secure protocols will be adopted (you'd also have to be able to trust them, that no NSA or other backdoor is hardwired in those new protocols). In short, this is not a simple situation and there is no simple solution.
- timtadh 12y agoI personally feel bad for Chet about this whole thing. For those of you (probably most of you) who do not know Chet has been maintaining Bash for free in his spare time for the last 25 years. He began working on it because he was not satisified with the shells available at that time: In 1989 or so, I was doing network services and server support for [Case Western Reserve] University (CWRU), and was not satisfied with the shells I had available for that work. [1] I had the priviledge of hearing Chet speak about his experiences maintaining Bash.[2] From my perspective he has done a really great job over the years making software that many people love to use and abuse. So while this is a really bad network security situation for the internet at large I think it is dubious to hold Chet or even Bash at particular fault. Rather, we are all at fault. We have been writing software that just shells out to Bash or sh or z-shell for years because it is convient. We could have easily have written our subprocess code in better ways but it was easy to use shells and we used them, even when we didn't really understand them. [1] http://www.computerworld.com.au/article/222764/a-z_programming_languages_bash_bourne-again_shell/ http://www.computerworld.com.au/article/222764/a-z_programmi... [2] The venue was Link State a student run conference here at CWRU
- deleted 12y ago[deleted]
- guelo 12y ago> The problem is that 5 years later, new software was developed (apache, dhcp, etc), that uses bash in child processes I don't think this history is correct. At the time, most systems used sh as the default non-interactive shell. The other shells such as csh, ksh and bash were considered to add interactive niceties, but programmers and sysadmins expected scripts to use sh. One of the reasons sh doesn't have a lot of wiz-bang features is that it needs to stay compatible and portable across all the different Unixes so that all the scripts, past and present, will work. And sysadmins liked this conservative approach. It wasn't until the rise of Linux, and the aliasing of /bin/sh to point to bash, that sysadmins started becoming comfortable with running bash as the default non-interactive shell. And that was only because bash promised to be fully compatible with sh. And bash was compatible but it also added new scripting features. But most developers and sysadmins rejected using these new features because you would lose portability to sh systems if you did so. That is until now, with the dominance of Linux and portability becoming less of a concern. So really this bug is the fault of bash's embrace-and-extend strategy.
- aidenn0 12y agoIt took a lot of discussions with pjb on irc for me to decide he is not actually a troll. His is very literal. The part where assigning a particular variable to any environment variable causes arbitrary code execution is a bug. The part where you can define functions by setting environment variables is a feature. It would be far better if the variable names needed a prefix (e.g. BASH_FN_foo='() {...}')., but even without that change, fixing this bug still preserves the case that allowing arbitrary data into the values of a whitelist of environment variables is safe. In general, allowing modifications to a subset of the environment (and by this I mean the entire system environment, not environment variables) needs to be safe. Allowing programs to upload arbitrary data to /tmp/uploads is safe, allowing programs to upload to e.g. ~/.profile is clearly not safe. In PJBs world it is not possible to set any environment variable to any value without reading the source code of every program that might possibly be called by any of your children. This is clearly not tenable.
- skybrian 12y agoIf an environmental variable is like a file, this bug is like automatically executing code stored anywhere in the filesystem if the file happens to certain a magic number. Using a prefix (if documented) is like looking in a certain directory. It should have been obvious that scanning ALL environment variables is a bad idea, if not for security than for correctness, because interpreting data belonging to another program is likely to cause unpredictable behavior.
- aidenn0 12y agoagreed
- kazinator 12y agoThis is completely wrong in numerous ways. Firstly, the "security concern" is definitely a bug. It is related to bugs in a feature; nobody is saying that that feature itself is a bug, though many are saying it's a "misfeature". So the idea that the feature itself is a bug isn't something that requires opposition. The idea that it's the Apache people's fault somehow, because they didn't inspect the implementation of something that they rely on, is wrong. > 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. Firstly, the CGI mechanism doesn't rely on Bash; it relies on the passage of environment variables. Secondly, for the shell language, there is a specification: POSIX. Someone calling a shell implementation should be able to rely on the interface contract. Nowhere in POSIX is it documented that code from environment variables is to be executed by the shell. Apache can run on systems that don't have Bash. A shell other than bash can be used for running a CGI shell script. You don't get the source code, necessarily; how can the Apache developers inspect the source code of a proprietary shell on a proprietary Unix? Even if the Apache or DHCP developers were to (insanely) take responsibility for this flaw, the workarounds in their code would be Bash-specific hacks: basically they would have to parse anything that goes into an environment variable and validate that it doesn't have the syntax which exploits the Bash issue. That would clearly indicate that it's a Bash problem. What also indicates that it's a Bash problem is the way it is being handled: fixes have been issued against Bash, not against other programs. The fire is where the smoke is, generally, and that's where you pour the water. Lastly, please don't post diatribes to a code paste hosting service; it is not your soap box. Thanks!
- whoisthemachine 12y agoI agree with this. Whenever something is interacting directly with a shell (or any other program that can execute passed in code dynamically for that matter), it should sanitize the input as to be certain nothing gets executed later, unless it wants something to be executed later. Whether that be Apache (if it's passing data or commands directly to shell that contain data from the external environment) or a CGI script it is calling, whatever happens to be interacting directly with the shell should be sanitizing its inputs.
- AgentME 12y agoAnd what sanitization should Apache be doing to all of the environment variables? A blacklist against "() {"? That syntax is specific to bash, bash's support for it is undocumented, and it can be in any environment variable. It's more than a bit arrogant of bash to have an undocumented claim on all environment variables.
- felipelalli 12y ago"I would argue that the bash security concern is not a bug. It is clearly a feature. (...)" The default excuse of all programmers. :)
- erikpukinskis 12y agoI don't understand this situation at all. Are people using bash as a secure jail and expecting it not to be able to arbitrarily execute code and access the user's complete environment? I think the maintainer is right. Bash was never marketed as a secure sandbox and anyone who uses it as such is taking that risk on themselves.
- dllthomas 12y agoMy understanding was that using this "feature" would sometimes lead to a crash of the executable. That seems to me to be clearly just a bug. Even absent that, contrary to the article, I think I'd still call this a bug in bash - but the crash (presuming I'm recalling correctly) makes this position absurd instead of just (IMO) incorrect.