+2  A: 

I guess you should use a salt when hashing the passwords.

eWolf
I suppose things like using third party providers like OpenId would negate this though?
Dan Atkinson
+1 Good point, but why OpenId negates? I don't know much about OpenId. I'm guessing with OpenId, we don't save the passwords in our own db, right? or wrong?
Chris
Just hashing the password is not enough, @eWolf is right that you need a salt in there.
AviD
@Chris, yes. You'd be right.
Dan Atkinson
+2  A: 

Use Captcha so that a bot cannot automatically create multiple accounts

YeahStu
There are better solutions than captcha, but for a low-value site it can be good enough.
AviD
Could you mention a few?
Fernando
+6  A: 

Use HTTPS, i.e. a combination of HTTP and SSL to provide encryption and secure identification of the server when submitting sensitive data like a password. The main idea of HTTPS is to create a secure channel over an insecure network. This ensures reasonable protection from eavesdroppers and man-in-the-middle attacks, provided that adequate cipher suites are used and that the server certificate is verified and trusted.

Pascal Thivent
Ok, +1. By HTTPS you mean the SSL certificate, right? And what attack would that be? I'm guessing man-in-the-middle?
Chris
I've updated my answer
Pascal Thivent
Thanks for the update, what do you mean by "adequate cipher suites" though? What are you referring to exactly? I thought the SSL certificate being signed (not self-signed) should be enough? Hmmm?!
Chris
+1  A: 

Filter user's data removing '<', '>' - simply html tags. If someone can view user's profile there are possible XSS attacks through data.

Andrew
or just convert < to and > to >
epochwolf
Chris, don't filter it - use your server-side language's escape functions on all user-provided data.
Peter Boughton
filter as much as you want, but its more important to encode the output - using context-sensitive encoding, not just HTML encoding. If you're on ASP.NET, use MS' Anti-XSS framework.
AviD
I don't know about the filtering/escapring for xss. I thought the agreed upon approach for xss was to whitelist (not blacklisting) i.e. allow not disallow. And I thought that a well-built library like HTMLpurifier was the advised way over cranking out your own regexes cleanups. No? Please verify/clarify. It's kind of easier too with a library :)
Chris
If you need to allow users to post HTML, you want something like HTMLpurifier to parse the HTML and provide a safe HTML output.But if users are just entering text that will be displayed, you only need to escape the HTML.If user-provided text will be output in JavaScript, you want JS escaping (which differs to HTML escaping); similarly with URLs and URL escaping, and so on.
Peter Boughton
@Peter Boughton To clarify, you mean for example, if registration page asks for their website for display as link, that's HTML, then I need HTMLpurifier. Correct? Can you give me an example of when "user-provided text will be output in JavaScript"? I can't think when we could need this?!
Chris
If I understood you correctly, if page has to display a link you just have to create <a href="$user_link">$user_link</a>, correct?About JavaScript example, let we have quite simple php script:<html><head><script type='text/javascript'>alert("<? echo $user_message; ?>");</script></head><body></body><html>In case of this script hacker may set $user_message to *** ");alert("Possible XSS Attack*** (without * symbols) and script will execute additional JS.So ' and " characters are critical for escaping or removing from string.
Andrew
About using 3rd party libraries. I think it's good idea, because it may not contain simple bugs(I mean filtering), which hackers can use for attack. But on other side, it may contain bugs.
Andrew
+1  A: 
  1. Use HTTPs or encrypt passwords before submition with MD5 and Javascript in clientside.
  2. Use Captcha.
  3. limit allowed characters for username.for example alphabet and numbers, dash(-) and dot(.).

PS. clientside encryption is not a secure way.but if you cant use HTTPs,clientside encryption a good solution.

and about limiting characters,its a simple way to protect your webware from injections(SQL/XSS).

Koosha
I wouldn't go md5 though and maybe not client-side. Any comments on this?
Chris
Security *must* be done server-side. Client-side is entirely untrustable. If you're using HTTPS then there's no benefit from client-side hashing, since the whole data is encrypted anyway.
Peter Boughton
Also, limiting username characters is not security, it's mostly just convention/laziness.
Peter Boughton
@Chris, you're right. Don't try to roll your own crypto, use standard HTTPS, and THEN hash on the server. Oh, and dont be using MD5 for hashing anyway - SHA-256 and up, together with salt.
AviD
SSL can be an inconvenience if you don't have a root CA signed certificate; some browsers make the user jump through hoops to get the untrusted certificate accepted. Client side hashing of passwords is a really good idea if you decide to go without SSL because your site doesn't really need the security, since it will keep an eavesdropper from taking the password and trying it out an other sites that do use and benefit from SSL encryption+authentication.
Inshallah
There is Javascript::SHA1 on the CPAN, which provides HMAC and SHA1 javascript functions. I guess you could HMAC the password with a salt and then do some rounds of SHA1, although I'm not sure how many rounds the browser can do in pure javascript :-)
Inshallah
+3  A: 

You should use e-mail verification

and addition to Koosha's answer : if you let usernames including such chars "#&?/" and create user pages like this site.com/user?me&you/ it may be serious problem in browsers. Please think it in url address bar of browsers.

rasputin
Because free e-mail accounts are really hard to get?
jrockway
@jrockway A few of companies block registration from major free email providers such as Yahoo, Gmail and MSN, but obviously this won't deter most folks. What it does offer is the ability to definitely link that email address to that user. This way, if the user got involved in any illegal activity on the site, then the email provider could be pursued through the courts for the IP addresses of that user, so that the ISP and police could identify them.
Dan Atkinson
@Dan Atkinson, which of course leads to another good point: log the IP address.
Inshallah
Feel free to add that as an answer of your own. :)
Dan Atkinson
@jrockway it leads spammers to give up creating a lot of user accounts. It will be time consuming for spammers and cause giving up.
rasputin
I don't get it, are you in favor of or against blocking the free email providers such as Yahoo, Gmail and MSN?! My point is many people don't have anything but those.
Chris
@Chris I think jrockway meant that users can get temporary e-mail address from e-mail address providers like 10minutemail.com and use it for e-mail verification.
rasputin
+2  A: 

If the routes on your website are set in a particular way (ie, going by the username, rather than their id), then having a username like 'admin' could cause problems. You should probably have an exclude list of possible usernames.

This caused problems in the past with MySpace, and people having usernames like login, and then decorating their page with a phishing form.

Edit:

As has been mentioned in the comments by AviD and Peter Boughton, it is also a way of misleading users. Let's say that a user has the username 'admin'. Then, in their user information page (assuming that they each get one that is available to all, like SO), they have some link in their about section that says like

For more information, visit our dev blog at mysite.cn/loginpage

Someone maybe sees, 'mysite' in the url, but doesn't really look at the TLD, which would be China (sorry China!), rather than the .com TLD your site is hosted on. So they click through, assuming it's alright (they came from the admin user page after all), and this site looks identical to yours but has a login page. So you 're-enter' your details, but nothing happens. Or it redirects you elsewhere.

This is often the tactic of bank scammers who wish to target customers, inviting them to go to their website to 're-enter a banking password'.

This is just one more form of a type of security known as 'Social Engineering'.

Dan Atkinson
+1 Good point. Can you please elaborate why admin would cause a problem. I'm guessing because a page could exist called www.site.com/admin/ but what's the connection?
Chris
Well, if you have routes where the user accounts are higher in the ordering than your admin section, then, with a user called 'admin', the site.com/admin/ section will become their user page. It could then be possible for people to user their pages to phish login details for example.
Dan Atkinson
Good explanation +1, although in my case, I'm not giving them their pages on the site.
Chris
This could also be an issue if there is any type of social interaction, as one user can be misled by the other users username...
AviD
Not just custom pages - for example, if users can message others then preventing names like "admin" might help prevent scammers from looking official.
Peter Boughton
Dan Atkinson
I have expanded my answer to cover more information about social engineering, and the act of manipulating unsuspecting users into performing actions that they mistakenly believe to be safe via the use of 'bad' usernames.
Dan Atkinson
+4  A: 

Use recaptcha or asirra to avoid automatic submission. That should stop the bots and script kiddies.

To stop hordes of humans from submitting spam (via mechanical turk or anything like that), log each attempt in memcached and as soon as you reach a maximum submissions from the same IP in a given period of time, block that IP for a few minutes (or hours, days, whatever...).

Fernando
+1 Good point, what is a good number before the block, because according to my knowledge, AOL users are bundled into a few IPs (correct me if I'm wrong), and also, how about those in the same company? They're under the same IP too.
Chris