The fact is that bash allows external entities to poison environment variables ahead of invocation, causing unintended behavior in bash when it is launched as a child process.
Well, it's not that it allows external entities to poison the environment, it's that it gives the finger to that basic secure programming practice where you should just assume that externally provided input is tainted data.
(you could say that there is a design vulnerability in CGI - and I would agree about that).
There's nothing in the CGI specification that requires or suggests that there needs to be any kind of intermediary in handling the reqests aside from the web server. The environment is a perfectly legitimate way of passing data, and if the web server calls the CGI safely (i.e. pipe()/fork()/exec()) there's no reason for a transient interpreter like bash to get involved. And, aside from security, the performance hit of invoking a shell just to launch another program makes it a bit silly to do it any other way.
And I'd point out that it's possible to explicitly control the environment of a subprocess (i.e. execle()), so anything calling a CGI program can at least sanitize things to minimize any damage. Not that the CGI should depend on the caller to sanitize things, of course.
On the other hand, the environment is a perfectly stupid way to pass code around.