How to deal with arrays of data in cookies - c#

I want to store data in a cookie and I am not exactly sure how I will go about it.
The data is the UserName, and Password values for the users that are logging into a website, e.g. sometime like this
UserName = bob, Password=Passw0rd1
UserName = harry, Password=BLANK
UserName = george, Password=R0jjd6s
What this means is that bob and george logged into the site and chose to have their password remembered, but harry chose for his password not to be remembered.
So on the login dialog a dropdown will be present with all the usernames in it 'bob', 'harry', 'george'. If they select the username bob the password will automatically be filled in, etc.
So how does that information need to be stored in the cookie? Like it is above, or does it have to be,
UserName1 = bob, Password1=Passw0rd1
UserName2 = harry, Password2=BLANK
UserName3 = george, Password3=R0jjd6s
Are the username and password values actually stored in the same cookie, or is each piece of data separate? Any information would be good.

As far as whether or not all information should be stored in a single cookie or multiple cookies depends on how many cookies you plan on creating and whether or not you want all the information to expire at the same time. Generally, for efficiency, you will group related data into a single cookie.
However, it is a bad practice to store passwords in a cookie, since this information would then be plain-text and easily readable by an attacker.
The following link provides some guidance on cookies and asp.net.
http://msdn.microsoft.com/en-us/library/ms178194.aspx

Related

Hashing user password - Identity Server

I'm currently working with Identity Server 4, at present when the user logs in I need to hash their provided password and then compare with the password stored in the database (also hashed)
After some searching, I was linked to the PasswordHasher within Identity Server to handle this:
var _hasher = new PasswordHasher<User>();
var hashpassword = _hasher.HashPassword(user, context.Password);
User is my custom class that inherits from IdentityUser, however, when checking the hashed password against the one in the database the hash is completely different, I have double checked the password and I can confirm it's correct.
Can anyone suggest why I maybe seeing a different hash compared to the one in the database?
Each time you hash a password with PasswordHasher<T>.HashPassword you will get a total different result because of the salt.
To verify such hashed salted passwords use the given method IPasswordHasher<T>.VerifyPassword.

Get unencrypted password from MembershipProvider

I'd like to get user password unencrypted. How to get this?
public static string GetCurrentUserPassword(string userName)
{
MembershipProvider p = (MembershipProvider)Membership.Providers["Default"];
MembershipUser obj = Membership.GetUser(userName);
return obj.GetPassword();
}
obj type : [Telerik.Sitefinity.Security.Model.User] = User "user1", Id={59d9813c-f88e-4790-9f19-3145ba8347d1}, Provider="Default"
password : "+HmReh/mzvIIuvYsM7+XdEoeQhI="
Why would you expect to be able to get the unencrypted password?
The only think you should be able to do with a stored password is use it to check the validity of the password the user has entered. For one-way hashing (and similar techniques) that involves applying the same transformation to the just-entered password (using the same salt where appropriate), and seeing whether you end up with the same hash.
You should not be storing any representation of the password which is reversible. That would mean that if an attacker gained access to your database (and any private keys), they would have access to your user's passwords directly - which is unacceptable, basically. (It wouldn't be so bad if everyone used a different password for each resource they protected, but many people don't.)
If the passwords are configured to be hashed and not encrypted, you can't do this. If you configure the membership provider to used encrypted passwords, then the GetPassword should do the trick. See PasswordFormat
That being said, I certainly can't disagree with Mr. Skeet's answer. You should really be using one-way hashed passwords if at all possible.
For dealing with forgotten password scenarios, take a look at ResetPassword.
The documentation for MembershipUser.GetPassword () says it all:
If EnablePasswordRetrieval is false, the membership provider will return an exception. If the provider supports passwords with a PasswordFormat of Hashed, you will be unable to retrieve the password for the membership user and should consider making use of the ResetPassword method when a user has forgotten his or her password.
I cannot think of any other way you would want to read the password .

Check Password change to ensure that new password doesn't equal last password used

I was just wondering how I could check (when a user is changing password after the password expires) how I could use (in WebMatrix) an if branch to ensure that the new password does not equal the previous password.
I don't think I want to check for any more password history beyond just the last password used, so as long as I can just check the previous password, I think that will be fine.
I could of course query the database and check, but as the password doesn't get stored in plain text, I know that this won't work, but I also checked on the WebSecurity methods here:
http://msdn.microsoft.com/en-us/library/webmatrix.webdata.websecurity(v=vs.111).aspx
and didn't find anything.
What is the best way to get this done?
Since the password is not stored in the database, there is no way for you to do this, unless you make a note of the password when the user first registers, and whenever they subsequently change it.
The irony here is that by storing the original password (even in an encrypted state), you actually reduce the security of your application.
For any who are interested, I did find a nice workaround to this question, that gets the job done just fine.
Keep in mind, though, that this will only work to check the very last password they had/have.
This is what I implemented:
First, of course, in the log-in page, among other code and after actual log-in, I have the obvious (to check if their password is over 6 months old and require change):
if(WebSecurity.GetPasswordChangedDate(username).AddMonths(6) < DateTime.UtcNow)
{
WebSecurity.Logout();
Session["gActionMessage"] = "Your password has expired. Please change your password by visiting \"Login\" then \"Change Password\"";
Session["gActionMessageDisplayed"] = "not";
Response.Redirect("~/");
}
Then, I came up with this on the "Change Password" page (actually the redirected page after email verification for password reset token, but you get the idea):
if(WebSecurity.Login(email, newPassword, false) && WebSecurity.UserExists(email) && WebSecurity.GetPasswordChangedDate(email).AddMonths(6) < DateTime.UtcNow)
{
WebSecurity.Logout();
errorMessage = "You cannot repeat your last expired password.";
}
The if branch here does three checks:
First, it effectively checks and logs them in if possible based off of what they typed in as their new password.
Secondly, it checks if the user exists (not really sure if I even need this, but whatever).
And lastly, checks to make sure that their password change date is over 6 months old (because the same page is used for "forgot password" stuff, so this just ensures that the right circumstances are met before erring in this way).
So, in short, if their new password is still sufficient to log them in (before it actually gets changed, of course), then it is a repeat and subsequently logs them out and throws the error message at them instead of changing the password. If it is not sufficient to log them in, then it can't be a repeated password, and (so long as it meets any other requirements) the password is then changed.
Hope this helps anyone, who may require a non-repeated password using WebMatrix upon password change, in the future!
Reference the System.Web.Helpers assembly,
Create a custom table called 'UserPasswordHistory' that contains stored hashed passwords in the 'Password' column with an incremented version number in the 'PasswordVersion' column, a row of which is inserted each time a user is registered or a password updated for a given user,
the following code works.
var userProfile = db.UserProfiles.First(x => x.UserId == userId);
var passwords = (userProfile.UserPasswordHistory
.OrderByDescending(x => x.PasswordVersion)
.Take(_configuration.PasswordCountBeforeReuseAllowed))
.Select(x => x.Password);
return passwords.Any(previousPassword => Crypto.VerifyHashedPassword(previousPassword, password));
To answer the question specifically asked _configuration.PasswordCountBeforeReuseAllowed would be set to 1

RavenDB Querying to check Username and Password

I'm fairly new to C# and RavenDB, so please excuse my lack of understanding.
I currently have a Windows Form Application. In one of the forms, I have two text boxes and one button. These two text boxes serve as the username and password inputs and the button is obviously there so that the user can login. When the user clicks on the button, a method is called and saves the content of the two inputs in two string variables.
At the moment, in my RavenDB Database, I have created two samples of username and password.
How do I appropriately check whether the username and password given from the user exists in the database.
Any help is really appreciated.
There are two ways to answer this question.
a) You can query for multiple properties using the Linq provider
session.Query<User>().Where(user=> user.Name = username && user.Password = pass).ToList();
b) The problem with this is that this assumes that you are storing the password as plain text in the database, which you should never do.
You can see how we implemented that in RaccoonBlog's RavenDB's sample application:
https://github.com/ayende/RaccoonBlog/blob/master/src/RaccoonBlog.Web/Models/User.cs
https://github.com/ayende/RaccoonBlog/blob/master/RaccoonBlog.Web/Areas/Admin/Controllers/LoginController.cs
As a matter of good security practice you don't store passwords at all, rather you you store the password's hash.
To store your password
Read the values on the server and generate a hashcode of the password. You should use crypto functions to generate hash (such as via SHA256)
Store a document in Raven DB of type User with his username and hashed password
To check if the user with the passed credentials is in the database
Query Raven DB and look for the user with the given name and password hash.
Sample code
var user = session.Query<User>()
.Where(u => u.UserName == "Alice" && u.HashedPassword == "hashPwd");

How to Extend Membership in Asp.net?

I am wondering how do I extend the membership stuff in asp.net?
When a user logs in I want to check the UserName and Password. Of course the standard asp.net membership does this(this it is ValidateUser()).
I also want to check another field called "institution". If a user types something in this box I want to verify if the "institution", "userName" and "password" match what is in the database.
If a user leaves the "institution" blank then I just want to use it default ValidateUser() method that is provided in asp.net and check only "userName" and "password".
So can I overload the ValdiateUser() method? Or will I have to write my own one to handle this new case?
Where would I store this "institution" field in the database? I heard something about people recommending the "Profile" table but I am not sure.
Also how can I change the membership to treat these as 3 different users
Institution: ABC
UserName: A09410515
Password: 1234567
Institution: GHA
UserName: A09410515
Password: 1234567
UserName: A09410515
Password: 1234567
So as my database should be concerned these should be 3 unique users. Of course in the case that my database already would have the same information stored in it.
For example.
Institution: ABC
UserName: A09410515
Password: 1234567
and someone tries to sign up with the exact same information for "UserName" and "Institution" then it would spit back an error about being duplicate names.
Yes, you can create a custom membership provider. Your provider will implement MembershipProvider giving you full control over creating an interface between the membership system and extended database schema. Writing A Custom Membership Provider for your ASP.NET 2.0 Web Site is a detailed example.
The lazy way of doing this would be to combine institution and username together to create the actual username.
Thus you'd have 3 distinct usernames: ABC&A09410515, GHA&A09410515, and &A09410515. Just don't allow a user to use & in a username.
Then, before creating the user or logging in you just combine the two strings together.
I can't think of any significant problems that can't be fixed with a simple hack (e.g. displaying the username (use username.split('&')[1] ), but JP's post is definitely the "right" way to do it.
James
You might use Application Name as the institution, that way you would have the same user name in different applications
Rodrigo.

Categories

Resources