Example scenario in an ASP.NET application using SQL Server membership provider :
1) a user can't remember their exact password, and tries many times in a short space of time to login with an invalid password (say 5 times in a 10 minute window). This locks out the user (i.e. sets the IsLockedOut flag of the aspnet_Membership table to 1).
2) user goes to the "forgot my password" screen to try to get a new password emailed to them. This screen uses the PasswordRecovery control. User enters their correct user id, but then cannot go further in the password recovery process, since the IsLockedOut flag is 1. (They don't even get to see their security question).
3) The user would then have to phone tech support to get themselves unlocked etc.
To reduce the burden on support staff, we are trying to reduce the times step 3 is required, by making the PasswordRecovery control (if possible), work with locked out users. i.e. when they enter their login ID, the security question comes up, and IF they enter the correct answer, the system will unlock the user, and email the new temporary password to them. I'm wondering if it is possible to tweak the PasswordRecovery control to do this. Or maybe this approach has security issues ?
You could create a custom membership provider that has an AutoUnlockTimeout setting that can be configured via configuration - Implementing Automatic Unlocking in ASP.NET 2.0 SqlMembershipProvider.
Related
I'm just looking into ASP.NET Identity, which seems that it is the most preferable solution for user authentication in ASP.NET apps these days (replacing all the ASP.NET Membership stuff from the past).
I am looking for a solution that would allow to maintain information about anonymous users. Even if the user is not authenticated, we can collect and store most of the profile data that we could store if the user was authenticated.
Even if the user is anonymous, it makes sense to store data like:
shopping cart
comments he's written on the site (so that he can edit them as their creator)
various site preferences (his preferred language, and many other settings)
Then when the user registers, we can offer to copy some of this data into his new user profile (or copy it automatically) depending on what data it is.
Is it possible to achieve this scenario with ASP.NET Identity? It seems that when a user is anonymous in ASP.NET Identity, he cannot have any user profile data.
In order to use the same tables to store all this information as for authenticated users, we might need to create a new user in the system for every new visitor that comes to the site and does some action that requires storing of some user data.
After that, we'd need to pass some cookie identifier to the user, so that we can always connect the data to the user, which can be seen as some form of authentication (although invisible to the actual user). That way, the guest user could actually represent an authenticated user of the system (maybe he'd just have a special role?), even though to his knowledge he's anonymous.
What do you think about this approach? Are there any ways where ASP.NET Identity can help with this?
I found these two related Stack Overflow questions, but I haven't found my answer in them:
Does ASP.NET Identity 2 support anonymous users?
ASP.NET Identity - Anonymous profiles
Edit:
I discovered that there's a mechanism called Anonymous Identification in ASP.NET that seems to solve part of the issue.
https://msdn.microsoft.com/en-us/library/91ka2e6a(v=vs.85).aspx
Maybe it can be somehow integrated with ASP.NET Identity?
Edit2: As noted in the comments, the documentation for Anonymous Identification seems to be outdated and it's quite probable that Microsoft will not be focusing on this much in the future. Solutions that work with ASP.NET Identity or other OWIN-based solutions are preferred.
Asp.Net Identity has no such thing, and it will not be secure identify the anonymous user even through hip IP or a Cookie in his browser, you can ask the user to register with very minimum info or through FB or Twitter to make the registration process as short as possible, and later he can complete his profile, this way you will make sure the data is linked to an actual profile.
ASP.NET profile properties allow your application to track and permanently store user-specific information. For example, users can specify a postal code or a favorite color scheme, and your application can store that information and retrieve it from anywhere in the application. ASP.NET automatically matches the current user — whether the user is anonymous or logged on — with the personal information that is stored for their user account.
Configuring Profile Properties
You will begin by configuring your application to enable profile properties. You will then define the first property that you want to track for each user. This property is named PostalCode and will be tracked for both anonymous and logged-on users.
Source: https://msdn.microsoft.com/en-us/library/taab950e.aspx
I am working on an old ASP.NET application whose end users authenticate with a local Windows account (no domain). We want to switch to using membership (via aspnet_regsql), and move the application to a new server. What's the best way to seamlessly do this?
My biggest concern is I don't want every single user to have to go through the "forgot password" process. Regarding passwords. As I understand, there's no supported way to get at the passwords in order to convert them to membership users. Is there an unsupported way to grab the passwords?
There are about 1000 users, and they log into the system rarely -- maybe a few times per year. Point being: there will be a huge % of users that won't log in until the old system is dead and gone.
My current thought is that we will need to implement two workflows:
Before migration to the new server, anyone that logs in will be authenticated with Windows, and their account automatically converted to a membership user. We will have their password from our custom login page.
After migration, anyone logging in that hasn't been converted to membership will have to go through the "forgot password" routine. We would present a message to them explaining why.
So bottom line: Is there a way to do this without requiring users to go through the forgot password process at all?
I would expect you cannot get the passwords from the windows accounts, you could import the users, create a password and send out an email to users with their new password or you could send a link for users to login and create a password or request a password reset given their email address?
The off-the-shelf ASP.net Membership Provider and tables do not appear to be PCI-compliant. Has anyone already implemented a PCI-Compliant Membership Provider for ASP.net? In particular, I am looking at the requirements for section 8.5:
8.5.2: Is user identity verified before performing password resets for user requests made via non-face-to-face method?
For this I am thinking an email with a reset token valid for no more than X hours. The default provider just generates a random value and sends it via email (although we could enable Security Question/Answer to fulfill this requirement).
8.5.5: Are inactive user accounts over 90 days old either removed or disabled?
Default provider does not support this action. We could tie into the OnLoggingIn to do some checks prior to allowing to the login attempt to proceed.
8.5.9: Are use passwords changed at least every 90 days?
Should be able to check this OnLoggedIn. If last password date > 90, redirect to the password change form instead of the desired content.
8.5.12: Must an individual submit a new password that is different from any of the last four passwords he or she has used?
I do not believe the membership tables for the default providers support this. We could add a password history table and stick an entry in every time someone creates a new password. These could then be checked in the OnChangingPassword event of the ChangePassword control.
I am fully capable of doing this myself, but if there is already something out there I'd like to take advantage.
Couldn't find any out-of-box solutions, so will be following James's advice and writing my own.
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 am using
FormsAuthentication.SetAuthCookie("username", true );
so that a helpdesk person could impersonate another person's ans go in and see what the account looks like. I as wondering if there is a way my code can determine that this session is running through impersonation (so that I can block a couple of pages and flash a sign saying "You are impersonating this user: username)?
The best thing to do here is make sure the helpdesk users have to be logged in as themselves before they go to the page that allows them to impersonate another user.
At that point, either save a session variable or send a second cookie down to the browser that identifies who they really are and any other info you need to keep up with. I prefer storing this in session variables because it is more secure and you remain in control of the information on the server.
The rest of your code would work mostly like it does now responding as if the user really were the one they impersonate, but any code that needs to test for impersonation can read the session or alt cookie to know if they are impersonating or not.