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.
Related
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 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.
I think, in almost all cases user preference data may be stored in a cookie with (almost) equally good results as when the User Profile API is used. Disadvantages of using cookies (for authenticated users) seem to be that a cookie can be deleted or time-out, in which case the user preference data will be lost. For anonymous users, if the preferences data needs to be persisted across sessions then a cookie will have to be used even when User Profiles are used.
So what are some of the biggest advantages/disadvanges of using either User Profiles or cookies for storing user preferences?
One of the benefits of registering on a site is that it remembers my preferences - if you're storing that information in a cookie on my machine instead of on your server then when I log into your site from another computer, I've got to set all my preferences up again - from a usability point of view, this is fairly bad.
For an anonymous user, storing the prefs in a cookie may seem fairly sensible - you don't know who they are, or whether they will comeback, and as you state, you can't work out from one session to the next who they are - however you'd probably be better off storing some sort of token in the cookie and mapping that to a preferences store on the server.
Also, I've noticed different browsers have different implementations for cookies - for example IE can now receive 50 cookies from one domain (up from the original 20), but it is still limited to a total of 4096 bytes for the entire cookie collection (and previous) - other browsers will support 4KB per cookie, rather than per domain.
Another disadvantage to holding all the preference data in cookies is that all of that data will have to be sent in every request from the client and in any response from the server whenever a change to the data is made. Whilst this may seem like a minor point in the age of broadband it is still an additional overhead. Using the Profiles API meands that the data is held at the server and only a session identification cookie needs to be sent by the browser.
Also, as you stated, for anonymous users if cookies are deleted then the user preferences held in the Profiles DB will no longer be accessible. However this will not be the case with registered users of your website. If they remove their cookies the server will still be able to retrieve their user preferences the next time they log in.
Cookies are limited in maximum length and they are using an implementation beyond of your control (after all, they are a feature of your visitors browser). Personally, I dislike relying on unknown third-party implementations I don't have any control over and if I have to, I'm trying to use it in the simplest way possible.
So from where I'm coming from, I would always store the user data on the server and just pass around a cookie pointing to that information.
Aside of not trusting the browser with a potentially big chunk of data (which may be lost, incorrectly stored or not stored at all depending on not only the browser but also, say, some antivirus application or whatever), this has various other advantages:
You are hiding your implementation from the user: If you store the data in the cookie, it's visible for anybody and can be analyzed or modified at will. This can even lead to users changing cookies to there liking and thus force you into keeping stuff around you probably want to get rid of just because some users are depending on your particular implementation at any time.
As cookies are stored in plain text, on shared machines, everybody can no longer easily see all the settings the previous user made, nor change them at will.
But the most important point remains the disconnect from not-quite-working browser implementations (just storing small tokens is the common, tested use-case)
Don't forget that one of the biggest disadvantages of using cookies is that they can be copied, so its dangerous to store authentication info on them.
I'm not familiar with User Profile API but I'm guessing it stores the information on the server(?). If thats the case then you could have a problem if you have to many users.
Overall maybe the best solution is to use User Profile if it guarantees the persistence of the information.
Keep in mind that its possible to write a ProfileProvider that persists user data in a cookie, so you can have the best of both worlds if you determine the state you want to persist is appropriate for cookies (size, security, etc).
Actually, you do not need to persist preference data in cookies for anonymous users when using the ASP.NET Profile Provider. Simply store the current UserID (which is some horrible looking session-related string) in a cookie. This becomes the previous UserID on subsequent visits, and then you can just grab the old Profile information and migrate it to the current Profile, or even authenticate them as that old anonymous Profile.
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).
I've got an existing site I'm taking over, and right now it stores, in a session variable, the id of the currently logged in user (if logged in at all -- otherwise I'm sure it is empty string or null or something).
The client now wants, after someone is logged in, to "keep" them logged in on that computer for an indefinite amount of time.
ASP.net Sessions have a maximum idle time of 1 day, I believe. The website isn't written all that well in the Flash portion (whole front end is flash) and the flash will process a login, then, as long as the flash isn't reloaded, assume that the user is still "logged in".
I think my solution is to ALSO store a client side cookie with some GUID value and hold in the database the associated user id...sort of like a session that never expires. So, when the page is loaded, I can check my cookie, use that to select the userid out of the database, and if we find one, then set the session value that says user 23 is logged in.
Does anyone see any issues with this perspective? Would you recommend something different? I really don't want to refactor a bunch of the existing code, but just slip this in on top...
PS -- security is not really a concern. The only reason they have people log in is so we can track orders by a person, but no money changes hands through this website. There is also no personal information that a user can view or edit, either.
This is how I do it. I actually have a cookie that holds their login and password, this way I can automatically log them in should they not be logged in. I expire the cookie after a couple of days of inactivity. The downside is that everyone forgets their password because the only time they really have to enter their password is when they come back from extended time-off.
This is for an internal application, with the same customer demands that you have and this works ... and makes the customer happy.
One thing we may end up doing is just using Windows authenication, might actually work better in this circumstance.
That's the way I do it, but the problem with it (at least I think its a problem) is that when you store the username and password in a cookie there is not any encrypting when you add the cookie. If you look at the cookies in your browser the username and password are displayed there plain as day. Is it possible to get some kind of encrypting on the cookies you store? Or how would you handle this?
Check this blog posting out http://timmaxey.net/archive/2009/03/06/asp.net-cookie-auto-log-in.aspx basically you needs to save the cookie with a guid a series, and a token, the token, in my case, changes all the time, the series is something that is generated based on something, like the guid and id combo or whatever, then the guid is always stored with the user. There is a cookie table to stored this info etc... pretty secure, not 100%, but pretty good... Tim Maxey
I recommend using the Enterprise Library Crypto App Block to store an encrypted cookie which is nothing more than a GUID. Get the GUID, and use a session table in the database to track user info.
At the session start event, get the user info and cache it.
Using the session object is not recommend for user info because it won't work on a web farm, unless you use a database for session state.
You're basically rolling your own session state at that point, and I'm fine with that. However, I would not go the route of storing the username/password in a cookie (even if encrypted). There's no way to expire that from the server-side. You can always remove your row in the table to force a user to log in again, but if they hold the username/password they hold the keys to the kingdom.