
The Password Reset Email Was Real. The Destination Wasn't.
The application sends the password-reset email. Its own template. Its own delivery system. The link carries a genuine reset token. But the destination belongs to someone else.
Spots 

The application sends the password-reset email. Its own template. Its own delivery system. The link carries a genuine reset token. But the destination belongs to someone else.

That is the unsettling part of password-reset poisoning: the application can assemble and deliver the dangerous message itself. The check was there. It never got its turn.
Coolify's advisory describes a chain involving trusted forwarded headers, a host-validation cache bug, and a reset URL derived from the request. On an empty cache, validation was skipped; the code that would populate that cache sat behind the skipped path.
The reported attack required the forged header to reach the application and the recipient to click the link. It was not an automatic compromise of every deployment.
The advisory credits bugbunny.ai and lists v4.0.0-beta.471 as patched. This is an analysis of that disclosure, not a claim of discovering or reproducing the Coolify vulnerability. Read the original advisory. Before looking at the fix, choose the destination
Here is a separate, deliberately small JavaScript model. All domains and tokens are placeholders. It sends no requests or emails. The token is DEMO_ONLY. Which server receives it if someone follows the resulting URL? The answer comes from the first line inside vulnerable. The forwarded value wins. The resulting link is:
Notice how little is wrong with this URL as a string. It parses. It uses HTTPS. It has the expected path. The token is correctly encoded.
The mistake happened before any of those checks could help: request metadata was allowed to choose the destination for a credential. The obvious repair leaves a second question Suppose you delete support for x-forwarded-host and use only headers.host.
In this model, the caller still controls headers.host. You have removed one route to the wrong destination while leaving another. For this single-origin example, the repaired function takes its origin from deployment configuration:
This matches the principle in OWASP's reset-password guidance: do not derive reset destinations from an untrusted Host header; use a fixed destination or validate against trusted domains. OWASP guidance.
The application sends the password-reset email.
