Request smuggling is about altering the number of messages in the HTTP protocol. You think there's only one message (like, one request, or one response) and another actor thinks there's more (like 1, 2 or 1 and half, etc.). It could also be that the load balancer counts 2 and the backends is counting 3, etc.
They're a lot of ways to make this happen. Usually you try to make information about the size of the message hazardous. And to do that you exploit strange HTTP syntax (doubling headers, conflicting headers, oversized attributes, control characters, bad timings, ...).
Being a Load Balancer OR being the backend server is sometimes not very important, usually a successful attack requires having different software on the load balancer and the backend server, that's important to get different interpretation of the same stream by the 2 actors.
Also, very important, HTTP pipelining is a key feature (introduced in HTTP/1.1, and it's not just Keepalive, it's having several chained messages). With pipelining you allow the stream of HTTP content to contain more than 1 message, this explains why a load balancer can be impacted by several responses when only one is expected, or why a backend can think there's more than 1 request while the load balancer thinks only one request was sent. Without pipelining any of the actor would just cut the stream after the first message.
One of the protection in HTTP servers against this bad usage of HTTP (altering the number of messages) is that this will usually generate bad queries, errors, that will generate either
400: Bad request or some
50x messages. Because the attacker is playing with parsing issues. And the HTTP RFC states that any error message MUST also close the connection (with the header
Connection: close and the tcp/ip socket really closed after that). It also states several times that strange syntax should generates errors.
This prevents some of the smuggling attacks, where the hidden query of hidden response would come after an error. If you close the communication channel any remaining content cannot harm any of the actors. So, send error, and close the channel after sending the error.
The linked CVE talks about not implementing this protection with error messages (closing the http pipeline by closing the keepalive channel when emiting errors), or not doing it well enough (maybe a read buffer was not flushed from the remaining data, for example).
I'm not sure this flaw was chained with real attacks, but it could facilitate attacks. You can generate HTTP activity after an error in the response stream. Not implementing the forced
connection: close on errors is a flaw that a lot of HTTP servers have, not only previous versions of Apache. I think what we see here is a way of preventing future issues by being more strict on HTTP RFC, and that's something Apache is doing more and more recently, like with the
HttpProtocolOptions Strict directive.