How to securely set up cookie-based authentication in classic ASP? - authentication

What would be the most secure method of using cookies to authenticate users in a classic ASP website?
I don't want to use the ASP Session object as the session cookie times out after a while, and I'd like the user to be able to keep their login to the website active between separate browser runnings.
However, I don't want to just create a cookie containing their user ID as that could be easily forged - so what are my options here? I guess some sort of encryption but I don't really know what the standard methods of doing this is.

Your options here are pretty much limited.
Get your users to log back in again; best security approach.

This obviously applies much wider than just ASP.
The best way would be to hash the password... you should be doing this in any case where you store it in database.
The hash is a cryptographic function - when you run a string through it (eg password) you get out a long code. If the input is the same, the output is always the same.
But (this is the important bit) its mathematically virtually impossible to reverse the process - to start with the hashed value and work out the password, other than brute force (someone hashes dictionary, or random strings and looks for output that matches the hash they have).
So when the user sets up account, they put in their desired password, but you hash this, and store that. Similarly in the cookie, after they login you store the hash, not the password, and this has is compared with the hash in the db.
The downside is you can't send a password reminder since you don't know the password - to you'd have to send a password reset link and have a system to do that.
If you're really paranoid you might double hash, eg when they login the password is hashed once and stored in cookie. Its then hashed again and compared with the password in db (which is also double-hashed).

Don't Do It
Maintaining a user login quote "...between separate browser runnings" is not secure. IMHO, when you close the browser a previous login should be gone. Suppose your visitor was using a community pc at a coffee shop.
If you maintain this login the potential for the next community user to open the browser, navigate to your website and "poof" they are automatically logged in as the previous user.

Related

User Authentication with Cookies Only

I am planning to use only cookies (and not sessions) to authenticate users around the private section of my website. I want users to stay logged in indefinitely, unless they logout themselves. It will work like this:
1. Upon successful login I generate a random hash and store it as a HTTP cookie on the user (using SSL). I also store the hash in my database, along with the user id and the user's device.
2. Whenever a new page is requested I check to see if the user has a cookie. If he has I get the hash and search it in my database. If I find a match and the device is the same I assume it's the user and give the page. If I can't find the hash or the device changed I assume it's not the user and ask for login again.
My question: would this method be acceptable, security-wise? I can't see why this would be less secure than using sessions (keeping the users logged in in both cases), as in the end the risk is the same, which is having an attacker discover the hash to impersonate the user. My defense against this is tracking the users device, so the attacker would need to discover the hash and have the same device.
Thanks for your feedback.
What you're describing is basically the session functionality offered by most languages/frameworks.
Just make sure your hash values don't use the time the user logged in as a source of entropy, ie. don't use h(username + login_time) because this could be brute forced fairly easily if the attacker knew the approximate login time.
What language / framework are you actually using? You'll find in most cases there's an option to use the session "functionality" with a persistent cookie (rather than a session one) which would save you implementing this from scratch and possibly creating additional security concerns.

Is there a safe way to send a user their password in clear text via email?

If I understand correctly, the biggest problem with sending a password via email is that it requires the password to be stored in clear text in the database. If the DB is compromised, the attackers will gain access to all accounts.
Is there a workaround for this problem?
How can one make sending a user their password via email as safe as possible?
The simple answer is: don't. If you think your database is insecure, an email is far, far less.
If you mean that you want to send them their password when they register, then you could do that before you store it in the database.
If you mean after they have registered, the only option is to store in plaintext (again, don't do this) or make a new, random password and send them that. It is impossible to get their password from the hash, which is why it makes the password storage safer. The best option is to generate a new (temporary) password you send them, or a token giving them access to a password change system.
You may want to consider a good hashing algorithm like BCrypt that includes a salt.
I don't know if my suggestion is feasible for your scenario, but you should better keep the data hashed or encrypted and send password reset links instead of plain-text passwords.
The moment the password is in cleartext in the email, it is inherently insecure.
As such, there is no safe way to send a password in cleartext safely.
You should not be storing passwords in cleartext in your database - you should be using salted hashes. When the user enters their password, you hash it with the salt and compare to the stored hash.
When people forget their password, instead of sending passwords by email, you should send reset links backed up by expiring tokens. These would generate a temporary new password (that would expire within minutes).
You should be hashing all passwords in your database.
sha1($_POST['password'].$salt.$username);
In the case of a lost password
A user requests a password reset link, which contains a hash generated in the "user_meta" table. When the user recieves this link, the hash is compared to that in the database, and the user will be able to UPDATE their current password with a new password.
The PTXT of the password is never reveiled.
You only compare hashes.
Yes, there is a common workaround.
Assuming that you have your users in your database.
You send the "password reset link" containing some "key" information, like a guid. An example link is a form:
http://your.site.com/setpassword?id=5b070092-4be8-4f4d-9952-1b915837d10f
In your database you store the mapping between sent guids and emails.
When someone opens your link, you check your database and you can find out who asks for the page - because any valid guid maps to an email. You can then safely let the user change his/her password assuming their email is not compromised.
When it's about to store the password, you never store it in plain text, you always hash passwords, using additional random salt to make the dictionary attack more difficult when someone breaks into your database.
There is a workaround which is less secure than a password reset but works if it is a requirement that users are sent a password, not a reset link.
What you do is you generate a new password that contains sufficient randomness to be very hard to guess, but is also formatted in a way that it is easy for them to remember and read out (say over the phone).
Something like: xyz-xyz-xyz-nnnn where xyz is an easy-to-spell but uncommon word and nnnn is a four digit number.
Then set it up so that this is a temporary password that needs to be changed on first login.
Set the password using the same logic you would use to set a normal password, so that it is correctly salted and hashed, and then send the password plaintext via email, like so.
Dear FirstName LastName,
You requested we reset your password.
Your new password is:
insipid-mirth-nonplus-9174
You will be able to log into the system once using this password, then you will need to enter a new password.
Important Caveats
This system has some serious vulnerabilities which make it unsuitable for websites where data security is crucial. There are more than these, but these are the ones I know/can think of:
Unlike systems which use a password reset link, this system could be used to lock someone out of the system (assuming you use it as is) unless you either require someone to fill out identifiable information before issuing the password reset, or send a "are you sure you want to reset your password?" email first. This would entail them clicking on a link with a GUID that goes to the server; at that point they may as well be sent to the password reset form anyway.
Since the password is being sent plain text via email, there is a danger it can be intercepted and the password can be used. Although to be fair this is not that much different than the risk of sending a password reset link.
If you ignore the risks in step #1 and you don't use a sufficiently random way of generating passwords (say you use a word list of fewer than 1000 items), someone who has hacked into your server will be able to retrieve the salted password hash and then write an algorithm that generates all possible passwords and checks them against the hashed password. Not as much of a problem if you use a cryptographically complex hashing algorithm.
If you want to send password to user via Email in cleartext and want to store those password into database as hash or any other format . It will be possible.......
Just you will have to follow some simple way....
1 .you will have to take those password as variable which will send from user.
2. When you store database then just convert it as you wishes format.
3. But when you send those to user by mail , That time just sent those variable password...
I think it will be helpful to build your concept about WAY.......

how to create a login module

i have to create a login module (The question is not language specific) but i am not sure how will i validate the user. Where and how will i store the passwords. Will i have to encrypt and decrypt my passwords and if yes what are the best suggested way to do them. Overall i need to know what all things i need to take care of for developing a login module where a user can login securely to access my site.
You don't need to decrypt your passwords in order to validate them, just one way encryption works fine for this. The idea is that when a user enters a password, you encrypt it the same way (using the same algorithm and "salt") and then compare with the encrypted one stored in your database. If they are equal, with a great probability it means it's the same original password. Thus you prevent anyone - the adminstrator or any attacker - from knowing the original passwords users use on your web site.
As for the rest, it's very simple, you have a table in your database which contains user logins, encrypted passwords, and possibly some profile information as well (full name, etc).
I usually use the following function to hash user passwords:
$password_hash = sha1(MY_SALT_1 . $login_name . MY_SALT_2 .
$password . MY_SALT_3);
where MY_SALT_* are arbitrary predefined strings, could be e.g. 'the dark', 'side of', 'the moon' (or actually the less related - the better).
Yes.Sure you need to encrypt users passwords.Because most of the users using the same password almost all sites.At that time they are not want to show the passwords to admin.And another reason is most of the time the site DB may be accessed not only by admin.Some other technical persons in the organization.So it is better to encrypt the password.SHA1 is the best way to make the encryption.
Where and how will i store the passwords.
I am not sure what you mean by this.Every one use the database for it like phpmyadmin.

Suggestions on storing passwords in database

Here's the situation - its a bit different from the other database/password questions on StackOverflow.com
I've got two sets of users. One are the "primary" users. The others are the "secondary" users. Every one has a login/password to my site (say mysite.com - that isn't important).
Background: Primary users have access to a third site (say www.something.com/PrimaryUser1). Every secondary user "belongs" to a primary user and wants access to a subpart of that other site (say www.something.com/PrimaryUser1/SecondaryUser1).
At mysite.com, the primary users have to provide their credentials to me which they use to access www.something.com/PrimaryUser1, and they specify which "subparts" the secondary users of their choice get get access to.
Mysite.com helps manage the sub-access of the secondary users to the primary user's site. The secondary users can't "see" their primary user's password, but through my site, they can access the "subparts" of the other site - but ONLY to their restricted subpart.
In a crude way, I'm implementing OAuth (or something like that).
The question here is - how should I be storing the primary user's credentials to the other site? The key point here is that mysite.com uses these credentials to provide access to the secondary users, so it MUST be able to read it. However, I want to store it in such a way, that the primary users are reassured that I (as the site owner) cannot read their credentials.
I suppose this is more of a theoretical approach question. Is there anything in the world of cryptography that can help me with this?
Text added:
Since most ppl are completely missing the question, here's attempt #2 at explaining it.
PrimaryUser1 has a username/password to www.something.com/PrimaryUser1Site
He wishes to give sub-access to two people- SecondaryUser1 and SecondaryUser2 to the folders- www.something.com/PrimaryUser1Site/SecondaryUser1 and www.something.com/PrimaryUser1Site/SecondaryUser2
Mysite.com takes care of this sub-user management, so PrimaryUser1 goes there and provides his credentials to Mysite.com. MySite.com internally uses the credentials provided by PrimaryUser1 to give subusers limited access. Now, SecondaryUser1 and SecondaryUser2 can access their respective folders on www.something.com/PrimaryUser1Site through the MySite.com
NOW, the question arises, how should I store the credentials that PrimaryUser1 has provided?
First rule: Never, ever store passwords!
Second rule: Calculate a hash over password, with additional salt, and store this in your database.
Third rule: A username (uppercased) could be used as salt, but preferably add a little more as salt! (Some additional text, preferably something long.)
Fourth rule: It doesn't matter how secure a hashing algorithm is, they will all be hacked sooner or later. All it takes is time!
Fifth rule: The security of your site depends on the value of what's behind it. The more value the content has, the more likely that you'll be attacked!
Sixth rule: You will discover, sooner or later, that your site is hacked but not through a hacked password, but through a loophole somewhere else in your code. The biggest risk is expecting your site is secure now you've implemented some strong security.
Seventh rule: All security can be broken, all sites can get hacked, all your secrets can be discovered, if only people are willing to invest enough time to do so.
Security is an illusion but as long as no one breaks it, you can continue to dream on! Always be prepared for rough awakenings that will require you to rebuild your illusion again. (In other words, make regular backups! (Preferably daily.) Don't overwrite the backups of the last week and make sure you keep at least one backup of every week, just in case you discover your site was hacked months ago and all your backups ever since are infected!
Now, if you really need to store passwords, use a hash over username plus password. Then hash again with hash plus salt! Better yet, create a list of salts (just list of words) and whenever a new user account is created, pick a random salt word to use to hash his username plus password. Store the index of the salt with the user account so you know which one to use whenever he logs on again.
And:
Eight rule: Always use HTTPS! It's not as secure as most people thing but it does give a feeling of security to your users!Since you've added text, I'll add more answer.
Since you want user1 to grant temporary access to user 2, you'll need a secondary user table. (Or expand the user table with a parent user ID. Also add a timestamp to keep track of the account age. User 1 can create the credentials and this is done in the normal way. Just store a hash with combined username and salt. In this case, use the username of user 1 as additional salt! Just make sure you'll disable the user 2 account when user 1 logs off or when a certain amount of time has gone by. And allow user 1 to enable all accounts again that he created, so they can re-use an account instead of having to create new ones all the time.
Security isn't a matter that depend on primary or secondary users. In general, treat them the same way! Secondary users have an added bonus that you can use the primary account as additional salt. The rest of it has nothing to do with authentication any more. It's authorization that you're dealing with. And while authentication and authorization have a strong relationship, be aware that you should treat them as two different, stand-alone techniques.
When user 1 logs on, he's granted access to the primary site. When he grants access to user 2, user 2 gets a reduced set of roles. But this has nothing to do with storing user names or passwords. You just have an user-ID which happens to be member of certain roles, or groups. Or not, but those would be inaccessible.
They're both just users, one with more rights than the other.
It depends on the kind of authentication your primary site and the secondary site agree on. Is it forms authentication, HTTP Basic or HTTP Digest? If is forms or basic then you have no choice, you must store the password, so your only choice is to encrypt it. You cannot store a password hash as you must present the clear text during authentication for both forms and HTTP Basic. The problems that arise from storing the encrypted password are due to either incorrect use of cryptography (ie. you don't use an IV or salt or you don't use correctly a stream cipher), but more importantly you'll have key management problems (where to store the key used to encrypt the passwords and how to access it from a non-interactive service/demon).
If the 3rd party site accepts HTTP Digest then you're in better luck, you can store the HA1 hash part of the Digest hash (ie. MD5 of username:realm:password) because you can construct the Digest response starting straight from HA1.
I did not address how the user provision the secondary credentials (ie. how you get the secondary site username and password n the first place), I assume you have secured a protected channel (ie. HTTPS from client to your primary site).
BTW this assumes that the authentication occurs between your primary and secondary site and the secondary site content is tunneled through an HTTP request made to the primary site. If that's not the case and the secondary site is actually accessed straight from the browser, then the secondary site must support some sort of pre-authenticated token based authorization of third parties like OAuth. Relying on credential authentication and storing the credentials on the primary site when the credentials are actually needed by the browser has so many problems is not even worth talking about.
Have you thought about accepting OpenID like Stack Overflow does? That way you are not responsible for storing passwords at all.
There is only one way to do this, and it is probably too burdomesome for the users.
You could encrypt the users password with a public/private key, the user keeps their key so the password can be unencrypted only when the key is submitted back to your server. The only way to make this simple would to be to have some web browser plugins that auto submit the information.
And either way, you could always packet sniff the communication to/from the server so its still mostly pointless.
there has got be a better way to explain this :(
but if you just want to know how to store the passwords safely do this:
username:john, password:pass
key = '!!#ijs09789**&*';
md5(username.password.key);
when they login just check to see if md5(username.password.key) = is equal to the one in the db - you can also use sha1 and or any other encryption method.
http://us.php.net/md5 & http://us.php.net/sha1
Never store passwords in a database but store a salted and hashed version of every password.
Check this article if this is chinese for you.
If you want to store the password yourself the best apporach is to use a one-way hashing algorithm such as MD5 or SHA-1. The advantage of this approach is that you cannot derive the password from the hashed value.
Precisely which algorithm you choose depends the precise products you are using. Some front-end tools offer these functions, as do some database products. Otherwise you'll need a third-party library.
Edit
Secondary users ought to have their own passowrds. Why wouldn't they?
You're making it too complex. You need to stop trying to mix authentication and authorization.
What you want to do is establish credentials for everyone, not worrying at this point if they are "primary" or "secondary" users. Then on the main site, where you manage the users and the primary/secondary relationships, you can do the logic of which users are primary or secondary and store all that stuff in a table. You grant or deny whatever rights and sub-rights you wish to each secondary user whenever the primary users update their relationships with them. When they're done, you finally need to replicate the appropriate user credentials from the main site out to the secondary site(s).
Then when a secondary user wants to head to any site in your farm, they authenticate themselves only as themselves - they never impersonate the primary user! And they have only the rights you granted them when the primary users gave them "secondary" status.
--
OK, since you shot that solution down in the comment, consider this:
First, I doubt anything will be truly secure. You can always recover the secret if you monitor the users' activity.
Now, this is completely off the cuff, and I haven't cryptanalyzed it, but check into what is called a secret sharing scheme. Store the "effective" or "real" main-site primary user password as the shared secret. Use the salted hash of the password given by the primary user as one secret. Use the salted hash of the password given by the first secondary user as another secret, and so on for each additional secondary user. Don't store the salted hashes! Just store the salt and the protected shared secret.
When a user enters their password, you retrieve the protected shared secret, use the salt and hash of their password to produce the salted hash, decrypt the protected shared secret, and now you've got the original primary user password.

How to implement Querystring authentication

I’m developing a website of a client and they are sending out newsletters to their customers (through the website administration interface)
The newsletters are personal to each of the subscribed recipients/customers.
Each recipient/ customer is also a user with a username/password that enables them to sign in on the website and manage their newsletter subscriptions and participate in the sites community.
This all works like a charm.
Now my client want a “Manage my subscriptions” link in the newsletter email that when pressed automatically signs the recipient/customer in on the website with no need to remember username and password.
This could be easily solved be making a link like this:
http://mysite.com/manage.aspx?user=peter&password=hounddog
Of course information should not be clear text but encrypted in some way.
This however poses a problem since the only way a user can be authenticated on the website if by providing a valid username and password.
In the name of security, passwords are stored as hashed values in the database making it impossible for me to insert the password in the link.
What is the best way to accomplish this without compromising the security?
You will have to compromise your security somewhat, if you want people to be able to login without entering password. Note that even if you had access to the password (as in your example), you would have to embed it in a mail massage which would be transmitted in plaintext.
You can create a Guid associated with each user and message, and append it to the URL, and allow that to login automatically.
You could perhaps isolate the permissions so that a login through a newsletter guid link only allows the user to manage subscriptions, but that a real password-login is still required to participate in the forum. In that case its pretty limited what havoc can be wrecked if someone gets access to a Guid from a mail message.
Could you not insert an encrypted user name bundled with the hash value of the password?
What I mean is, encrypt & encode the user name to always be a particular length or to have a known break character in it then append the passwords hash value. this way, you could break apart the query string easily while still having the user name and password securely encoded. A straight compare of the hash values would be enough, with the unencrypted, decoded user name to allow access.
What about using an encrypted cookie that contains an access token ?
This cookie would be delivered after a successfull authentication by a separate page.
This kind of token can also be part of the URL query string.
Also you might consider using secured https instead of http.