I'm starting to size up a project where I feel security needs strike a little closer to home. What tools and techniques could I look at to attempt to raise an alarm when a valid login is used, but the owner of the login has given it away or had it stolen. I would prefer ASP.NET, then MVC 3, oriented stuff.
This is not a silver bullet, but perhaps you should consider employing some kind of two-factor authentication. For example: when a user creates an account with you, you require that she provide you with a phone number where she can receive text messages as part of the registration process. Then, when she attempts to log in, you text her a temporary authentication code to be used in combination with her username and password.
This ads an extra layer of security to the system, because an attacker would have to both know her username and password and have physical access to her cell phone in order to compromise her account.
I hope that's helpful.
Seems like you would get a lot of false positives... but you might try checking what IP address the login is coming from. Most people will log in from the same IP address most of the time, so when that changes, it's at least a warning sign. If you want to be very strict about security, you could maintain a whitelist (for each account) and require that they get their IP address added to the whitelist before logging in.
My bank (Chase) does this by checking a secure cookie during my username/password login. If the cookie is missing or corrupted, they require a second form of authentication, which is either a code sent via text to my phone number on file or via email to my email address on file. Once the second form of authentication is complete, they set the secure cookie and then I can login from that browser with only username and password.
Implement your own Membership provider and add field locked to model,
check for user being locked on login and do some actions
It might be useful to think of the factors of the Authentication process, so that you can be sure that you are sufficiently covering things. You can easily get ridiculous with the layers of assurances, but I happen to find that most banks now have a variation on a simple model. All of this is, of course, over SSL
User submits account name. Additionally, you can require a secondary piece of information, last 4 of account number or year part of date of birth.
Optional, but a good idea: present the user with a counter sign, that is something that verifies the identity of the server. The user selects this at registration and should be looking for this every time they attempt to log in. This aids in preventing phishing.
System checks to see if the current system using IP lookup or cookie is associated with the account. If not, presents challenge question along with password input. Otherwise, presents just the password input.
Complicated, but can actually be done in 2 pages and more secure than is usually required.
I've presented this workflow to a few bank clients and they usually remove one or two of the checks for a balance of user friendliness.
With phones with text capabilities being so common, the idea of SMS verification code as mentioned by others is also a good idea, though I haven't implemented this in a system yet, personally.
Related
Currently i'm trying to implement a device two factor authentication in which every time a user logs in, if that device wasn't recognized with the user the user will have to perform some sort of two factor authentication.
Currently i'm using System.Web.HttpBrowserCapabilities however, this is becoming a huge inconvenience because of automatic browser upgrades. I'm curious if someone has a better method or any suggestions.
Thanks!
Use a device cookie
It says "this user has successfully authenticated on this user agent in the past"
You probably want to include their username (or user id), a timestamp, and a random value (a nonce), and an HMAC of this info
Make sure this cookie is marked "secure" (HTTPS only) and "HttpOnly" (cannot be read by JavaScript)
When a customer signs up for a site, we want to let them know whether a username/email is available for use.
We have a httphandler that serves the purpose of feeding a jquery script that showsthe customer whether or not their desired username/email is available.
The question is:
The service can clearly be seen being called when you view the request in fiddler.
It shows /emlhandler.asmx?name=xxxxxxxxxxx#yyy.com
From the handler, a simple 0 or 1 is returned to indicate whether or not the name/address is available.
My concern is that this seems like a major security issue that would be very easy for an inexperienced person to exploit to discover all the users on the site.
So friends, how do you protect your site info and still allow the ajax callback to provide a great user experience?
Thanks.
Heath
You are being slightly paranoid here. Every site that allows user registration has to do something similar. One thing you can reasonably do is add a slight delay (maybe 2 or 3 seconds) to the handler's processing in order to reduce the likelihood or ease of a brute-force attack. Frankly, I don't think anyone would bother.
Another option is just to ignore repeated emails and send a verification email before a user's registration actually becomes active. If a new user attempts to use an existing email, the original email owner receives the verification and can cancel or ignore it. But I don't recommend this.
I'd say the vast majority of the sites I've used will just immediately say "this email address is already registered... did you forget your password?" Just knowing an email address is already in use on a given site does not in itself represent a security breach.
One possible solution would be to only enable POST requests for that method.
And since you cannot invoke services from JavaScript from another domain (XSS - Cross-site Scripting) without your authorization, then you would be protected.
However this technique would prevent malicious users from calling your web service to discover user names but this wouldn't prevent the user to automate a process to simulate user entering data in a text box to force a call to the service, in that case, perhaps you could allow just a number of requests per user in an X amount of time.
You could keep track of the number of attempts using the Session object from your web service
Another approac would be to add a re Captcha to your site, however this would decrease the level of responsiveness if you used to allow your users to capture a user name and as soon as they write you call your service. Implementing would require your users to write the auto-generated captcha in order to submit your data
I'm using Forms authentication in ASP.NET MVC website and I store user account login name in AuthCookie like this:
FormsAuthentication.SetAuthCookie(account.Login, false);
I want to ask if there is a possibility that user on client side will somehow manage to change his login name in AuthCookie and thus he will be for example impersonated as someone with higher privileges and authorized to do more actions than he is normally supposed to have. Also is it better to save in this cookie user account login name or user account ID number?
The cookie will be encrypted and decrypted on the server side, so unless the user can crack the encryption key, he or she won't be able to do this.
As long as the information you store uniquely identifies your user, the choice as to what that information is is entirely down to the requirements of the particular application.
No it is not possible (well, in theory maybe but it's not feasible in practice). The value of the authentication cookie is encrypted so the user can not tamper with it. It is a good idea to store the (unique) login name in the authentication cookie, because when the IIdentity object (HttpContext.Current.User) is restored, the value that you passed to SetAuthCookie is used for the Name property of the IIdentity. The Name property will be shown if you use the LoginStatusControl, for example, so it's a good idea that the value of the Name property makes sense to the user.
Cookies are encrypted so chances for that a quite slim. But still.
More than one property approach
If you'd like to make your security even tighter you could save username as well as user ID or some other data that can't be guessed from the username. The combination of these makes it safer because if you can guess one it harder to guess others and use the correct combination of them. Ie. If you guess other user's email/username it's a bit harder to guess the same user's ID, because they're not related. So the more unrelated properties you combine the more steps it takes to get the right combination.
Logon security token approach
You could use an alternative approach described in this scenario:
User logs in.
Generate a random security logon token that can be of random length with some minimum length defined and save it against user in the data store. This is probably not a problem while it's quite common that other data is stored at logons as well like LastLogonDate info.
Use this token and save it in the cookie instead of usernames or other info.
If user logs-out, clear logon security token from the data store
User logs in again... go back to 1 and create a new token again and use it in this session.
This way it will make it safer on the long run, because this information will change on each login and if user does manually logout you can always clear that token from the store, so it won't at all be possible to inject someone else's identity. This does make it a but more complicated to use permanent cookies though but it can still be done.
This approach is not bullet proof but it provides additional security level that prevents the same attack over and over again when one account has been compromised. And also when one account is compromised it doesn't mean that others can be as well. If your security tokens are long enough it would be much harder to start a brute force attack on your site and while this kind of attack would be executed security tokens will change so it is definitely safer.
I have designed login page for one of our website where I have used following resources
Login Name and Passowrd lable and textboxes
Combo box for multilingual support
Submit button.
Now to make this page more secure I am planning to use following extra points.
CAPTCHA/ RE-CAPTCHA
Number of Retry: block after 3 unsuccessfull login attempt.
I have seen these extra things by visiting other sites. I would like to know
Whether these extar point makes somediffrence for security?
How should we implement number of retry? When should we again unblock user account.
What is right approach?
You could use ASP.NET's login control and the default SQL membership provider. If you do this, implementing the number of retries before a user is locked out is as easy as setting a config value.
Take a look at MSDN here, and scroll down to "Using the SQLMemberShipProvider" section.
Look at the NoBot control from the AjaxControlToolkit (http://www.asp.net/AJAX/AjaxControlToolkit/Samples/NoBot/NoBot.aspx). That provides some "bot protection" without the user needing to decipher a captcha.
General - Require a strong password and limit the login tries/user (not IP/cookie). If you add a five minute lock-down for a user name after three fails a bruit force attack would take more years than you site will live (dictionary attacks are not possible since you require strong passwords)*.
Protect your users - In your form, don't post the password in clear text, post a hashed version eg.
md5([your domain] + [password])
The reason you add your domain is to protect the hash of the password from the server owner (you), so if your user DB get hacked the hashed passwords you stored are useless even if your users use the same password on multiple sites. If you like stronger hash you could look for some SHA version. Make a js script that replaces the password with the hashed one before sending. Remember to have this hash calculated on the registration page, never let the password be sent from the browser in clear text. You don't want to know it!
http://en.wikipedia.org/wiki/Cross-site_request_forgery, also have your server sign the cookie values to make cookie forgery harder.
Encryption - Either use TSL/SSL or get a RSA script and encrypt your form data with your severs public_key.
Man-in-the-middle - The hardest threat to guard against, I guess that https is the easiest way but a trusted certificate costs money. If you self sign users today don't bather to look if it's the right cert or not, this requires too much form the users. Buy a cert or hope you don't have a man-in-the-middle.
I would never use re-captcha for login since a lock-down of user name is more effective and less disturbing for a user. Though re-captcha is good for account registration so you don't end up having a lot of scripted accounts.
Limiting login tries/username could be used to block a user to log in. Bruit force attacks are still available since they can attack a lot of usernames and not only one, thus keeping the attack under the limit/username block. But for a site with few (less than 10.000?) user accounts you should be quite safe.
If you are updating an existing site that has had security issues, captcha can't hurt. If it is a new site, is it public or for internal use? You can always add this later if you run into issues. If there are sensitive materials, you'll get more mileage out of enforcing strong passwords from users (though this can be annoying to them) than you'll get out of captcha (also annoying).
Several options here. You can record IP address on each attempted login and record failed attempts. 3rd fail from same IP inside of 15 minutes blocks further attempts (every attempt fails with locked account message). Additional attempts reset the 15-minute "timer." Really, there is no timer, but with each attempted login, the log it checked to see whether it has been locked within the last 15 minutes.
The login attempt log can be stored in many ways -- often a database table. There may be value in keeping a record of every login (in case there is ever a breach), or maybe you only want failed logins. Optionally, you could remove failed logins from the log when the user successfully logs in. You could have a database routine that cleans up the table from time to time of failed login records that have exceeded the waiting period (15 minutes, or whatever).
Obviously, 15 minutes is arbitrary -- this can be 1 minute or 24 hours or until the user calls your customer support line to get it reset.
I'm rewriting a website and going from a home-grown authentication model where users logged in with their account id (numbers) and password, to .NET FormsAuthentication where users will login with a username that they choose (or is available) and a stronger password. There are over 38K existing accounts and I'm trying to decide if the existing users should re-register or if I should write some code to do this on their behalf. I've already ruled out creating the usernames for the users because they won't be able to change their username. Luckily we don't have any users named Brenda Utthead.
If the user re-registers, some may gripe about having to do this step again and it may raise some support calls, but I stay with the standard process that everyone has to do. Or I can allow the user to login with their existing userid and password and then optionally give them a grace period to convert their account. I'm hesitant about the latter because it's special code and a possible threat vector because it bypasses the standard authentication mechanism and allows users to log in using less secure credentials.
This application currently accounts for about 40% of our website traffic and I'm not worried about users not coming back to the website because of the possibility of them having to re-register.
What does everyone think?
If you want your users to come back your best bet is to convert their accounts and send an email explaining the transition.
Do not make them re-register whatever you do.
You'll lose half of your users if you do that.
Give them a service so that they can enter their previous user id and have them provide their email address. Email them at the address provided and have them login with their email address as their new user name.
I am about to do the same thing. I am writing a migration page where the user logs in with his/her existing credentials and behind the scenes, I write out to the asp.net membership tables. Do a check first to make sure they haven't already migrated for all subsequent visits.
Don't make them re-register. A little work on your side is all it takes and you need to keep your customers happy.
After listening to everyone's suggestion, I've decided to modify the login. I look at the username they provide and try to guess that they're an existing user. Then I look them up in the old table and if I find a match take them to a conversion screen. There they can quickly convert their account or skip the whole process and login temporarily. The conversion form has fewer fields to fill out b/c I was able to authenticate them against the old user table so I don't need them to provide as much info.
I'm not thrilled with skipping the conversion but that option is only offered for the first 45 days from go-live.
Either convert them or find a way for both membership models to exist together, and somehow convert each user across at login or something.
Think about how long it took to get the 38k members and ask yourself if those were all wiped out, would those same people go through the hassle of signing up again. If you've got a really strong community you should be ok, the hit would just be a matter of time till you're built up.
The other thing you could do to mitigate the risk would be to send out a email, although spam blockers may filter them you could get to a high percentage of your users and tell them about the new membership stuff. Might get some older people back to the site as well in the process.
The biggest challenge is converting all the data that is associated with the user's accounts. People are going to be really upset if they've built up some sort of reputation that you're going to destroy with a new membership system.
This website is a check your balance type of website. It's not a banking site per se, but it exists as a convenience tool to users. I don't believe it would be realistic for users to cancel their accounts because they are forced to re-register.
I do like some of the ideas I'm reading in the responses though.
I would migrate their information and then on their first login ask them to confirm that their membership info is correct (just to be anal).