I haven't had to tackle a login process before so this is new territory for me and all I seem to be finding on Google are conflicting methods of handling this process, so I was hoping someone could help clarify.
So far I have a salted SHA1 hash made from mixing username, password and my salt variable.
When the user logs in their credentials get hashed, then this hash gets sent to sql and if found comes back with a UserID (or something). So I know they are authenticated.
With that I can handle their session with session variables.
Is that right so-far?
Anyway, I wanted to have the option of "remember me" and was looking at storing something in a cookie but am not sure what to put in there as, as-far-as I am aware storing the hash would be pretty much the same as putting their username & password in plain text.
I'm confused, can anyone shed some light?
Thanks in advance
You are usually better off using the authentication methods provided by your platform than creating one yourself. There are a lot of non-obvious problems that you can easily leave yourself open to. Which platform are you using? Are you using a web framework?
General purpose hashes like SHA1 are inappropriate for password hashing as they are optimised to be very quick, when you want something that is very slow. For discussion of this, see How To Safely Store A Password.
Anyway, I wanted to have the option of "remember me" and was looking at storing something in a cookie but am not sure what to put in there as, as-far-as I am aware storing the hash would be pretty much the same as putting their username & password in plain text.
Hashes are designed to be one-way functions, so no, it isn't the same as putting their username and password in plain text. However if you do it that way, you'll have to create a way of letting somebody authenticate with the hash instead of their username and password, and that is the same as storing their username and password on the client (as far as you are concerned, anyway).
I like the fact that you have used salt for your hashing but I don't think it's necessary to use the username for hashing only password+salt should be enough. Specially it will inflict an overhead of rehashing if you want the option of changeable usernames for your system.
For remember me option, I don't think you should store any credentials at client side cookies. Only the session ID should be enough. If you want to make it really secure you should use client-side certificates that are issued by the server.
http://it.toolbox.com/blogs/securitymonkey/howto-securing-a-website-with-client-ssl-certificates-11500
Your first login process is correct and up to todays security standards with the only exception that you may want to choose another hashing function over sha1.
Sha1 is very quick and therefore brute force attacks to crack a hash are faster. So if your hashes (database) and token (source code) get leaked, the passwords can be cracked.
One countermesure is to use a slower hashing function (see Jims answer for an article about that)
But the best of course would be not to leak your hashes in the first time.
A possibility for the remember me function is to let the user keep the session cookie for longer. For example Magento and Zend Auth does this.
This is however very ugly because you are likely to get hundrets of thousands of sessions stored on your servers, even for users that never return.
The far more elegant way is to store this information client side.
Sidenote: Of course you shouldnt put too many cookies on the client because they get transmitted with every page request. But a login cookie is a very valid case to do so. A good practice is to store the login cookie at the client side and populate the server session with data saved in a database at login which is marked in a session. This way you eliminiate continous database requests and have a good user data registry. Of course write has to be done to the database and session directly or better to the database and then somehow flushed to the application (full or incrementally).
Putting the hash in a client cookie isnt like "plaintext". However its ugly and awful and insecure on many levels.
There are some different approaches but they mostly involve some hashing again.
The most common and easy one is something like to put a cookie with user_id=john and user_token=HASH($userid.$appsecret) on the client. Or to store them as one in one cookie.
This is kinda secure but I prefer the following method:
Generate a string that holds:
userid ; user agent ; first two ip segments ; current timestamp ; your application secret token
Run it through a good hashing function and store a cookie at the users client that looks like
auth=userid;timestamp;hash-of-the-above
When the client logs in via cookie you re construct taht string from above but take the timestamp and user id from the cookie. Generate the hash and see if it matches. Then you have validated that it is the cookie you generated for that ip adress segment and this user agent at the specified time
Sidenote: first two ip segments rarely changes with dynamic isps. you can leave them away too, its for extra security.
What is the main advantage of thsi method?
The client or you can invalidate all login cookies by setting a timestamp. Only cookise that have been generated afterwards are accepted. You can also implement a timeout.
This is good if you want to "remote logout" form a public computer where you forgot to log out or something.
I think functionality is very important and with this method you dont have to keep track of single login cookies (like google does).
Hope this helps you.
You can scale this method to any level of security you like and adjust it to your needs.
your authentication is just fine. If you want to make it even more secure you could transmit the login information with a SSL encrypted connection so nobody can read what's going across the network.
The remember token is quite simple let's say you want a remember me function that is valid for 14 Days.
A stranger with no authenticated session comes to your site:
Check if there is a remember me token in a cookie
If yes, check if you can find this remember me token in your database and check if the "valid until" column is still valid (date comparison)
If you find a valid token you can set the user id and authenticate his session
If you don't find a valid token redirect the user to the login page if necessary
When the user fills out the login form and authenticates him sucessfully:
Generate a token using an appropriate hashing function. The token you hash could look like "[Timestamp]---[userpwd]" so it's (almost) definitely unique! Save the token and the date until the token is valid (+14 Days from now as example) to your database connected with the user's id. If there's an expired token, replace it because you don't need to store expired tokens.
If the user logs out by clicking the logout button or similar just delete the token record in your database and the user's cookie.
That's it!
If your platform (web server etc) supports HTTP digest authentication, i would strongly advise you to use it. It was designed by people who know more about security than either of us ever will. It doesn't send passwords over the network. It is supported by all modern web browsers, including mobile devices. If the browser has the password stored, it happens transparently during connection, giving you the 'remember me' functionality without needing to go anywhere near a cookie.
The only thing it doesn't do is let you use a nice form - the use will get a dialog box from their browser to log in.
Related
I want to show the password from database which is encrypted.
How to show envrypted password in admin dashboard page?
I have seen laravel documentation fo rehashing but i am not understanding it
Laravel hashes passwords, which is irreversible. You pretty much can't ever see a password once it's been hashed and stored in the database, and this is by design. It isn't encrypted, and thus, cannot be decrypted.
When someone signs in to the application, their password is HASHED, and then compared with the hash in the database. This is done so that a password can not be stolen from the database.
Now, I don't know your application or your circumstances, but I would consider it very bad practice to allow even an admin access to users' passwords (there shouldn't be a reason in the world they need to see those).
Here's a great video on the matter.
But if you REALLY still need this to happen, consider a making a custom authentication driver that at least uses encryption instead of hashing (but again, probably a bad idea). I found a few different tutorials with a quick google search.
Background story: We run a website with thousands of users and a handful of admins. Some of these admins don't need all-access to the website, so I want to restrict their access by giving them individual permissions.
My plan is to set a Session on user login with the users perimissions, if given any. However, I'm concerned that this might be an unsafe action.
Can a Session be manipulated by a user client side? In this case a regular user could gain access to the admin features if they knew the permission names and set a Session for themselves.
I found some related questions on Stackoverflow, but they didn't give give me enough information on the subject.
You are already providing the login for admins and users so save type of permission they have and give them rights to modify data according that..And as long as your session state is encrypted it is very hard to manipulate on client side.
If you have concern about security of your existing session and cookies here is link to make it secure.
Secure your Session
This is full Article how to make your session and cookies secure...
You can indeed store server variables such as the user-agent, the ip address and so forth (and even JavaScript variables), but they are only good for validating that the persistent cookie data matches the client's new connection. The ip address isn't a good idea except when you know that the client (like you only) isn't going to change on every page load (a la AOL).
Modern web browsers and 3rd party services like LastPass can store login credentials that only require a key press (and sometimes not even that) to send the data to the login form. Persistent cookies are only good for those people who refuse to use what's available otherwise. In the end, persistent, non-session cookies are not really required anymore.
There is no such thing as secure cookie UNLESS it's transmitted over SSL only. It can be mitigated some when using a persistent non-session cookie (like remember me), by doing exactly what you're doing, but not in the same way you're thinking of doing it.
We have merchants logged in to a system, from which we want to link them to our Magento instance with some kind of admin token that will log them in directly without them having to manually login.
I see the rp_token field in the admin_user table but that appears to be related to a password reset, which probably isn't what we want.
Have done a bit of searching, found this thread which is related but is dealing with secret keys specifically (which will probably be my second challenge to resolve after resolving this one).
I'm guessing this isn't supported in core, but maybe there's a good extension out there to do it?
Or if not, what would be the best approach to implement? I'm guessing there is probably an event I could hook to look at a GET or POST param (which maybe could be a hash of the username and hashed password), then bypass the normal login() method which relies on username and plain text password.
That feels like it could be a little risky though? Any thoughts?
That feels like it could be a little risky though? Any thoughts?
This is extremely risky, but it can be done safely. I can speak on a similar issue I had in developing QuarkBar, an administration bar for Magento that is set to release this weekend.
So to show the bar, I need to verify the admin is logged in. Unfortunately that's hard to do on the frontend module, since there are two separate sessions. So to get around that I've created a quarkbar_session table. I use OpenSSL to store a secure crypt key once an admin is logged in, that I then check for on each request and match it to a cookie. If it matches, the admin is verified.
It's a little different from what you want of course, since I first set the key when the admin is logged in (it's an observer event). But it should get you started.
Source (NOT ready for production, use it for ideas): https://github.com/zschuessler/QuarkBar/tree/master/app/code/community/Zaclee/QuarkBar
Also, note that I'm storing the secure key so that I can access the admin backend. The solutions in your link say to disable it. You don't have to, check out QuarkBar for implementation.
Ok, I'm new to web development, so I might be getting some of these terms wrong. I apologize in advance.
I am having trouble understanding the different elements of authentication. Every method seems to be advised against by someone, though not always with clear reasons. I am building a web app for a company that will have access to a database, so I would like to make sure it is secure.
So the there are three places I have seen commonly used to store information.
FormsAuthentication.SetAuthCookie(). This stores a session cookie that will exprire with the browser, and nothing sensitive is on the client. However, it can only store one value. This stackoverflow answer shows a method of storing multiple values here, but the guy who gives it says not to use it, though not why.
FormsAuthenticationTicket. I don't know where this information is stored, but it allows for a simple method of storing multiple values. Securing it, according to the documentation requires calling Encrpty() to store, and decrypt() to retrieve. This seems wasteful, but what do I know.
Session["SomeRef"] = new CustomObject(). The second answer in this question explains how to do this, but a comment to it calls it dangerous because it can be stolen. This looks like the best method to me, because the information is still stored on the server, and can store multiple values.
I cannot find any comparisons for these methods, or good explanations on the "best practice" way of storing multiple pieces of information after authenticating a user. The information is just the User's name and their userId.
Here is some further clarification to help you decide.
SetAuthCookie can be implemented in a way to store multiple values. In practice, however, you usually can't store enough to avoid a database lookup. It's best to store the user name (unique identifier) and load more information during the request. As your question suggests, you shouldn't store sensitive information on it. You should assume that all information sent in a cookie can be decrypted and read and you should take precautions that that information can't be used maliciously. All session cookies can be stolen and I'll explain why in a moment.
FormsAuthenticationTicket is the same API as SetAuthCookie but at a lower level in the Framework. With SetAuthCookie, Encrypt() and Decrypt() should be happening anyway (it's the default configuration.) It's not wasteful but use method 1 instead because it's easier.
Session has some limitations. Notably, by default it's process-dependent. That means that when the server restarts or more than one web server is involved, your session is lost and you have to authenticate again. It is the easiest to use and fastest when using the default memory session storage (InProc). You can use sql storage or a dedicated session server to overcome the process-dependency.
All three methods are considered dangerous for the same reason all cookie-based authentication systems are dangerous: because the cookie's value can be sniffed over wireless and reused to take over a session. This is known as sidejacking and it also applies to scenarios 1 and 2. The way to prevent this is to implement HTTPS. Then, the cookie transimission (and everything else) is encrypted at the network level and can't be stolen.
TLDR; Use SetAuthCookie and HTTPS
NOTE this answer has been edited several times for clarity.
I'm currently making a site using GWT, being hosted on AppEngine. I'm making it with my own logins that I'm making (I know Google provides something with GWT, but I need my own login system), and I've been trying to figure out sessions for quite a while now. I've found a few tutorials, and one of the sites that I was reading is http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecurityFAQ
There is a section there on "How to Remember Logins". I know how to get the session ID and store it on the client in a cookie through an RPC call. What I don't understand is, eventually after a day or so, the user comes back and I'm supposed to get the session ID from the cookie and send it back to the server. What am I supposed to do on the server in order to securely evaluate if session ID is still legal, and pull up all the necessary information about the user?
Additional questions:
1. What would make the session ID change?
2. What if the user was on a laptop, and the user went somewhere else. Would he still be able to be securely logged back in without having to type in his login and password again?
Thanks!
~Scott
Similar question: question on GWT, Cookies and webpage directing.
One important thing you should remember: don't rely on cookies alone - transfer the session ID/token in the payload of the request too and compare it with the cookie value on the server side. This will prevent XSRF attacks. That's the sort of thing you should be worried about.
The policy on how to deal with session IDs depends on how seriously you take security in your application and what type of application is it. For example, you can login with the same token on GMail from different IPs - I presume they allowed this because it's common that the user's IP changes over sessions. They did however add a feature that allows you to see from which IPs the user logged in recently. And don't forget about users with dynamic IPs (quite a large number) - if you keep track of tokens and IPs you will basically disallow those users to be kept logged in between sessions.
What am I supposed to do on the server
in order to securely evaluate if
session ID is still legal, and pull up
all the necessary information about
the user?
You should keep track of the session IDs/login pairs in your DB.
What would make the session ID change?
Either it expires or the user tries to log in with a token that is not bound to their IP. You could add your own rules too - like the number of logins, etc. For additional security, you can generate a new session ID/token on every new login/session (the user authenticates with the old token, the server checks that it's valid and sends back the user the new token he/she should use from now on).
To remember logins you need to securely generate a unique session id. Normally, this is placed in a cookie. I would recommend using a framework that does session cookies for you. Getting it wrong can leave your site wide open to abuse. Things to consider include:
Do you need to worry about cookie stealing. The user's IP address should be encoded in the session id, or linked to the session id. Check the IP address on every page access.
Ensure your logins are on encrypted sessions. Otherwise, you expose credentials in plaintext on the network.
How long should sessions last. They should time out after a fixed time limit. This can be hours or days long.
Remember me should be different functionality on a different cookie. It needs to contain something that can be used to indentify the user. Depending on your security requirments it may need to be an encrypted value. This cookie can have a longer timeout.
Answers to your additional questions are.
Nothing on the client side is likely to change the session id. The session id should be regenerated every login.
Depending on how secure the session id is, they may have to login. Secure session cookies often encode the IP address to prevent cookie stealing. If so, the laptop user would need to login again.