Hacker News new | ask | show | jobs
by nbpoole 4986 days ago
I have no Django experience, but I can imagine how an attack like this works:

1. Links are rendered via some function that takes into account the user's current request (ie: to determine the proper host)

2. The "reset your password by clicking this link" URL is generated using that function.

3. I am a malicious attacker and I submit a password reset request for your account.

Thus, I can control the URL that is sent to you in an email.

1 comments

Yup, that's basically it. It essentially makes phishing Django sites easier. The vulnerability could allow an attacker to send a legit email -- sent by the real site itself -- with a link that sends a user to a malicious site instead.

[So please upgrade!]

The fix as described seems to just check the Host header for suspiciously-formatted information. Is that also enough to prevent other wrong (but well-formatted) Host values from being used?

It seems to me that the deeper risk is composing emails based on a passed Host value, rather than any sort of canonical name the site has for itself. Does the warning about avoiding domain-wildcard setups mean this is still a risk, even after the latest fix?

> The fix as described seems to just check the Host header for suspiciously-formatted information. Is that also enough to prevent other wrong (but well-formatted) Host values from being used?

No, it's not. As the release notes say, "Some attacks against this are beyond Django's ability to control, and require the web server to be properly configured"; see https://docs.djangoproject.com/en/1.4/topics/security/#host-... for details.

Thanks for the clarification.

The note about "beyond Django's ability to control" seems hand-wavey to me. Avoiding the use of the Host header to construct URLs -- not necessarily as a quick fix, but as a long-term better-practices goal -- would put safety against such attacks completely under Django's control, and provide a bit more defense-in-depth.

But most sites need to work from at least two hostnames (dev and production). So would you need to set up a whitelist in advance?
Not exactly, but sort of.

My estimation of what would be most safe/robust would be for a deployment to know its own canonical hostname/base-URL, and use that trusted value in construction of emailed URLs.

Perhaps this would be one of the explicit parameters that vary in dev-vs-production configurations. Maybe it's looked up from a key that's the local hostname. Perhaps, even, it's looked up based on the 'Host' header, but if the key is absent it's a failure. (Then, the available mappings are a sort of whitelist.)

The official Django recommendation essentially equates to, "be sure to enforce a whitelist on passed 'Host' values at the HTTP server". So it's leaving responsibility to the many alternate web server configurations Django devs might be using... while it could be solved definitively with a slightly different practice inside Django itself.