$link = 'https://'.$_SERVER['HTTP_HOST'].'/reset/'.$token;

I wrote this line. More than once. It builds the link for a password reset email, and it looks like it reads something about the server. It does not. Host comes from the client, same as any other header.

Kohana 3.3.4 shipped this month with a fix around exactly this, and the topic is bigger than one framework.

The attack is short. Someone requests a password reset for your email address and puts his own domain into the Host header. The application trusts the header, builds the link, sends it. You receive a real email from a real site with a link to evil.example and your real token in the path. You click. He collects the token. Host header poisoning, and no framework protects you from it out of the box.

Two fixes.

Hardcode the base URL in config and build every absolute link from it. Simplest, works everywhere, my default now.

Or validate: a whitelist of trusted hosts, reject everything else. Kohana has trusted_hosts for this since 3.3.4, Symfony has a trusted_hosts setting too. And if you sit behind a proxy, X-Forwarded-Host plays the same role and lies just as easily. Put it under the same check.

The rule is older than any of this. Everything in the HTTP request is user input. The URL, the cookies, the headers, all of it. Host just hides better than the others: it describes what the client claims about your server.

I grepped our projects for HTTP_HOST after the release notes. Four hits. Three of them mine.