If you can feed arbitrary environment variables to a program, you can cause it to do just about anything by having it load libraries of your choosing. In most cases this is not considered a vulnerability in the program receiving those environment variables, but rather in the mechanism by which an outsider could feed in arbitrary environment variables.
However CVE-2014-6271 is different.
There is nothing wrong in having untrusted data in an environment variable. One just has to ensure it doesn't get put in any of those environment variables which can modify program behavior. Put a bit more abstract, for a particular invocation, you can create a whitelist of environment variable names, which are allowed to be specified directly by an outsider.
An example which has been put forward in the context of CVE-2014-6271 is scripts used for parsing logfiles. Those may have a very legitimate need for passing untrusted data around in environment variables. Of course the name for such an environment variable is chosen such that it doesn't have any adverse affects.
But here is what is bad about this particular bash vulnerability. It can be exploited through any variable name. If you create an environment variable called GET_REQUEST_TO_BE_PROCESSED_BY_MY_SCRIPT, you wouldn't expect any other program besides your own script to interpret the contents of that environment variable. But by exploiting this bash bug, every single environment variable becomes an attack vector.
Notice that this doesn't mean names of environment variables are expected to be secret. Knowing the names of the environment variables involved doesn't make an attack any easier.
If program1 calls program2 which in turn calls program3, then program1 could pass data to program3 through environment variables. Each program has a specific list of environment variables which it sets and a specific list which it acts upon. If you chose a name not recognized by program2, you can pass data from program1 to program3 without worrying about this having any adverse affects on program2.
An attacker knowing the exact names of variables exported by program1 and names of variables interpreted by program2 cannot exploit this knowledge to modify the behavior of 'program2` if there is no overlap between the set of names.
But this broke down if program2 was a bash script, because due to this bug bash would interpret every environment variable as code.
 
                