Critical Mistake #1: Non-HTTPS Login pages (even if submitting to a HTTPS page).
Most webdevs know that HTTPS is comparatively expensive-- the multistage handshake with multiple roundtrips and cryptographic operations is inherently less performant than straight HTTP. A few years ago, someone got the bright idea that login pages should be served via HTTP to reduce this performance hit.
The thinking goes something like: "Well, since the HTTP POST containing the user's credentials is sent via HTTPS, any man-in-the-middle can't see the data."
And this seemed like a reasonable idea. The practice became even more popular as banks and credit card companies decided that customers should be able to log in directly from the HTTP-delivered homepage. Three of my financial institutions offer this "convenience". One of them even draws little lock icons near the login box and provides a phone number for customers to call so they can convince them that it's safe.
There are two problems with this practice: One fairly obvious, and one slightly less obvious. The first problem is simple: How does the user know that the form is being submitted via HTTPS? Most browsers have no such UI cue. (Pretty much everyone turns off the "Warn when sending unencrypted form data" option within 2 minutes of installing the browser.) Even supposing there was a UI cue that the form was targeted at a HTTPS page, how could the user know that it was going to the right HTTPS page? If the login form was delivered via HTTP, there's no guarantee it hasn't been changed between the server and the client. A bad guy sitting on the wire between the two could simply retarget the POST to submit to a HTTPS site that he controls. Oops.
Think that's bad? There's an even more sneaky attack the bad guy could execute. The event model in HTML is pretty rich, and one of the things it can do is listen for keystroke events. So, the bad guy could simply rewrite the login page HTML to leak keystrokes to a server he controls, every time a key is pressed. Unsecured login form + Man-in-the-Middle+ 5 lines of JScript + Serverside keystroke collector = Bad News.
(Food for thought: The keystroke-sniffing attack gets even worse if your JS can run in the browser chrome, a feature offered by some browsers.)
Critical Mistake #2: Mixing HTTP Content into a HTTPS page
Some HTTPS pages pull in assorted resources over HTTP, which leads to the annoying "This page contains both secure and nonsecure items" prompt. Why does this hassle exist? Is it really so bad if some files get pulled down via HTTP, if the main body of my page is delivered via HTTPS?
The answer is, of course, yes, this is a bad thing. For one thing, it's impossible for the user to tell what parts of the page were delivered securely, and what parts were not. And worse, if a man-in-the-middle can rewrite the HTTP traffic, he can, for instance, rewrite the HTTPS page using standard DHTML. Or, he can scan the page for any information of interest (e.g. a credit card number) and POST that data to a server he controls. Using HTTP-delivered resources on a HTTPS-delivered page pokes holes in your secure channel. Don't do it.