If you construct your hash correctly, the url click will have to come from the IP address that requested the reset. This would require the MITM to spoof the IP and/or falsify headers. While this is possible, the more unique you can identify the hash to the system in question, the more difficult it becomes to "end-around" the hash.
It is also recommended that the guid be a one-way hash of certain criteria. It is also possible to encrypt system data in the request using a public key that a private key unlocks so that when the url is clicked, this same public encrypted system data must accompany the hash, and the only system that could unencrypt these values would be the private key held at the server. Basically a psuedo-PKI attachment to the hash.
When I was in the Air Force the security rule we had was: When setting or resetting passwords, do not send the user id and the password in the same email. That way, if someone is intercepting emails snooping for passwords, he has to successfully intercept BOTH emails, and be able to connect them, to breach security.
I've seen a lot of sites that use the "go to this URL to reset your password". Maybe I'm missing something -- I don't claim to be a security expert -- but I don't see how that is any more secure than just inventing a new, temporary password and sending it. If a hacker intercepts the email, why can't he go to that link and see the new password as well as the legitimate user could? It looks to me like extra hassle for the user with no security gain.
By the way, congratulations on NOT using security questions. The logic of this device escapes me. Since the dawn of computer security we have been telling people, "DON'T make a password that is information about yourself that a hacker could discover or guess, like the name of your high school, or your favorite color. A hacker might be able to look up the name of your high school, or even if they don't know you or know anything about you, if you still live near where you went to school they might get it by tryinging local schools until they hit it. There are a small number of likely favorite colors so a hacker could guess that. Etc. Instead, a password should be a meaningless combination of letters, digits, and punctuation." But now we also tell them, "But! If you have a difficult time remembering that meaningless combination of letters, digits, and punctuation, no problem! Take some information about yourself that you can easily remember -- like the name of your high school, or your favorite color -- and you can use that as the answer to a 'security question', that is, as an alternative password."
Indeed, security questions make it even easier for the hacker than if you just chose a bad password to begin with. At least if you just used a piece of personal information for your password, a hacker wouldn't necessarily know what piece of personal information you used. Did you use the name of your dog? Your birth date? Your favorite ice cream flavor? He'd have to try all of them. But with security questions, we tell the hacker exactly what piece of personal information you used as a password!
Instead of using security questions, why don't we just say, "In case you forget your password, it is displayed on the bottom of the screen. If you're trying to hack in to someone else's account, you are absolutely forbidden from scrolling down." It would be only slightly less secure.
Lest you wonder, when sites ask me for the city where I was born or the manufacturer of my first car, I do not give an actual answer tot he question. I give a meaningless password.
</rant>
Best Answer
It depends on the the level of security you are aiming for, support costs and usability concerns.
Emailing a password reset link is the preferred approach for a number of reasons:
Support Costs - This is the biggest factor from a business perspective. Users often forget even their password hints or use a fake mailing address or forget their user name. All of these are legitimate concerns for which you might get support requests. This in turn creates another issue, you have to establish the legitimacy of the user by asking them about recent account activity and what not. If you don't provide that level of support a lot of novice users will be disappointed. Emailing a password reset link mitigates these concerns because the users typically have one or two email addresses and they can easily recover their username/password by providing their email address.
Security Concerns - This is the biggest factor from a technical perspective. There are various concerns here which you have to weigh. A compromised email account means the hacker can go to access all of the users' services which allow a password reset link to be emailed. You can settle for middle ground which is to email a password reset link to the user which in turn asks the user a password hint question after which it allows them to reset their password. Again, you should never expose the user's password in any medium. In fact, if you have the capability to show them their password your system is already insecure because it implies you are not storing them using a secure hash like SHA-1 and a developer in your company can get at everyone's password.
Usability - This is the biggest factor from the user perspective. Emailing a password reset link requires the user go and check their email address which can means the time to achieve the task can go up to 2 or even 3 minutes. However, I would think that this is not a big deal. Most users don't seem to mind this because they feel they are at fault and this is a security measure in their best interest. I am only hypothesizing from personal experience and users in general might feel differently. I would put security as a higher priority than the user experience because users will rarely if ever need to retrieve their passwords (user has not logged in for a long time and forgot his password; user had saved his password in the browser which was reinstalled and some other edge cases).