This means that all the traffic in $coffeeshop is now being routed through my machine.
Now whenever I see someone logging into facebook, I'm just pretending to be facebook, using my very own self-signed certificate.
The user on the other end wouldn't notice at all if they didn't warn about self-signed certificates.
Now the user thinks they log into facebook while they are actually logging in at my proxy.
Browsers that blindly accept self-signed certificates would make for a much worse attack than firesheep (Firesheep allows hijacking of active sessions, man-in-the-middle-ing SSL connections gives you the password for offline use.
You could of course try and work around this by having browsers "blow up" if the certificate changes at all. But what if facebook has to renew their self-signed certificate? Ok. Then let's just blow up if the signer authority changes? How do you make sure that the facebook who has signed the current certificate is actually the real facebook and not me impersonating as facebook?
Accepting self-signed certificates might work with some kind of web of trust. Imagine the browser showing a message like:
"Do your trust this site? 99.992% of our users have seen the same certificate, so it's pretty certain that this is really the right site"
This, again, works until Facebook has to change that certificate:
"Do you trust this site? 0.00001% of our users have seen this certificate. This is probably a phishing attempt"
Don't get me wrong. I think that the current CAs overcharge for their services. I do think that there are way too many CAs already listed in your browsers. I do think that the whole process is too complicated.
But over the years, I really came to an understanding that this, for the moment, is a necessary evil.