James Kettle provides a good write up on Practical HTTP Host Header Attacks. They are summarized here with a description of the Django ALLOWED_HOSTS strategy.
Password Reset Vector
The password reset email vulnerability that the documentation alludes to is a result of Django and/or its applications using and trusting the HTTP Host value, which is provided by the client (sound like a bad idea?). The Host value is copied directly into password reset emails, providing a handy injection vector.
The cache poisoning variation relies on this behavior, and also on differences in the way the HOST header is handled by servers and caching solutions.
HTTP_SERVER vs HTTP['HOST']
As Kettle describes, due to RFC2616, it is possible with compliant servers to use a discrepancy between HTTP_SERVER and HTTP['HOST'] to deliver arbitrary Host strings.
By exploiting different formats and using special characters, an attacker can cause an 'allowed' Host to be interpreted maliciously in different contexts. This is again an error in the application that trusted the Host string.
As the release notes provided by Catskul summarize, the Django solution is to have the user put the allowed hosts directly into the project code. By forbidding any other hosts that don't match
ALLOWED_HOSTS, the injection vector is eliminated (a "white listing" approach).
This is something of a clunky solution, as James points out, but it's also pretty effective.
Keep in Mind
It's possible to use wildcards in a project's settings, in which case this feature doesn't help secure anything.
A secure application developer will avoid using the HTTP Host value in any meaningful way.
Carlos Bueno, Cache Poisoning (2008)